码迷,mamicode.com
首页 > 其他好文 > 详细

UVA 1377 Ruler bfs+状压搜索

时间:2015-01-22 11:12:21      阅读:168      评论:0      收藏:0      [点我收藏+]

标签:

题目链接:点击打开链接

题意:给定n个刻度。下面是n个刻度。

要构造一个尺子使得上面的n个刻度能直接量出来。

且要满足尺子上的刻度线个数最少,最少的情况下尺子最短。

第一个刻度总为0

题目保证总是存在<7个刻度线的解。

思路:

bfs,每次枚举新加一个刻度后,哪些可以直接量出来,用二进制表示,然后暴力搜

剪枝:

1、若加入一个新刻度后并不能多测量给定的n个刻度那么加入的刻度就无效(即加入前和加入后的状态相同)

2、尺子的长度若大于最大刻度则无效


import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.TreeSet;
import java.util.Queue;

public class Main {
	static int N = 55;
	int n, max;
	int[] a = new int[N];
	int[] id = new int[1000005];
	class Node{
		TreeSet<Integer> G;
		int state;
		Node(){
			state = 0;
			G = new TreeSet();
		}
		public Node clone(){
			Node hehe = new Node();
			hehe.state = this.state;
			Iterator<Integer> it = this.G.iterator();
			while(it.hasNext())
				hehe.G.add(it.next());
			return hehe;
		}
		void put(){
			System.out.print(state+":");
			Iterator it = G.iterator();
			while(it.hasNext())
				System.out.print(it.next()+" ");System.out.println();
		}
	}
	Node p;
	TreeSet<Integer> ans = new TreeSet();
	Queue<Node> Q = new LinkedList<Node>();  
	void BFS(){
		Q.clear();
		p = new Node();
		p.G.add(0);
		Q.add(p);
		while(Q.size()>0)
		{
			p = Q.poll();
			if(p.state == (1<<n)-1)
			{
				if(ans.size() < p.G.size())continue;
				if(ans.size() == p.G.size() && ans.last()<=p.G.last())continue ;
				Iterator<Integer> it = p.G.iterator();
				ans.clear();
				while(it.hasNext())
					ans.add(it.next());
				continue;
			}
			if(p.G.size() == 7)continue;
			Iterator<Integer> it = p.G.iterator();
			while(it.hasNext())
			{
				int num = it.next();
				Node next;int i;
				for(i=0; i<n; i++)
				{
					if((p.state&(1<<i))>0) continue;			  //刻度已选取
					int v = num+a[i];
					if(p.G.contains(v)) continue;//刻度已可表示
					if(v>max)  continue;//超过最大刻度,不需要
					next=p.clone();
					next.G.add(v);
					Iterator<Integer> it2 = p.G.iterator();
					while(it2.hasNext())
					{
						int x=abs(v-it2.next());
						if(id[x]!=-1)						
							next.state|=(1<<id[x]);						
					}
					if(next.state!=p.state)
						Q.add(next.clone());
				}
				
			}
		}
	}
	void init(){
		ans.clear();
		for(int i = 1; i <= n; i++)	ans.add(cin.nextInt());	
		max = ans.last();
		for(int i = 0; i <= max; i++)id[i] = -1;
		Iterator<Integer> it = ans.iterator();
		n = 0;
		while(it.hasNext()){
			a[n++] = it.next();
			id[a[n-1]] = n-1;
		}
	}
	void put(){
		out.println(ans.size());
		Iterator<Integer> it = ans.iterator();
		while(it.hasNext()){
			out.print(it.next()+" ");
		}
		out.println();
	}
	void work() {
		int Cas = 1;
		while(true){
			n = cin.nextInt();	if(n == 0)break;
			out.println("Case "+(Cas++)+":");
			init();
			BFS();
			put();
		}
	}
	Main() {
		cin = new Scanner(System.in);
		out = new PrintWriter(System.out);
	}

	public static void main(String[] args) {
		Main e = new Main();
		e.work();
		out.close();
	}

	public Scanner cin;
	public static PrintWriter out;
	int upper_bound(int[] A, int l, int r, int val){//upper_bound(A+l,A+r,val)-A;
		int pos = r;
		r -- ;
		while(l <= r){
			int mid = (l+r)>>1;
			if(A[mid]<=val){
				l = mid+1;
			}
			else {
				pos = mid;
				r = mid-1;
			}
		}
		return pos;
	}
	/*class Queue {
		int[] queue = new int[N+10];
		int front, rear;

		// front <= rear
		Queue() {
		//	queue = new int[x];
		}

		void clear() {
			front = rear = 1;
		}

		boolean empty() {
			return front == rear;
		}

		int size() {
			return rear - front;
		}

		int front() {
			return queue[front];
		}

		int rear() {
			return queue[rear - 1];
		}

		void push_rear(int x) {
			queue[rear++] = x;
		}

		void pop_front() {
			front++;
		}

		void pop_rear() {
			rear--;
		}
	}
/**/
	int max(int x, int y) {
		return x > y ? x : y;
	}

	int min(int x, int y) {
		return x < y ? x : y;
	}

	double max(double x, double y) {
		return x > y ? x : y;
	}

	double min(double x, double y) {
		return x < y ? x : y;
	}

	static double eps = 1e-8;

	int abs(int x) {
		return x > 0 ? x : -x;
	}

	double abs(double x) {
		return x > 0 ? x : -x;
	}

	boolean zero(double x) {
		return abs(x) < eps;
	}
}


UVA 1377 Ruler bfs+状压搜索

标签:

原文地址:http://blog.csdn.net/qq574857122/article/details/43015577

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!