codeforces #300 B. Quasi Binary

题目大意:


给定一个数字n<=1e6


然后有很多个形如  1 10 101 10101 这样01组成的【十进制】数字, 记住,十进制!


问n,【最少】由哪些数字组成。


显然任何一个数字k,都可以由k个1组成。。。 这题要求用最少个数字组成。


思路: DP


f[i]表示拼出i所用的最少的数字数量。


f[i] = min(f[j] + 1)    且 i-j 的数字为  形如1,10,101这样的数字。

pre[i]表示 i是从哪里转移过来的。  为了输出结果的时候用。 这个比较好想。

这个转移是n^2的。


预处理出所有的1,10,101这样的数字,一共不到70个,DP的时候f[i] 只从 f[i - p[j]] 转移。  p[j]为 形如1,10,101这样的数字当中第j个。


然后就能AC了,题目没有恶心的地方。


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.StringTokenizer;

public class Main
{
	static int n;
	static InputReader reader = new InputReader();
	static int num[] = new int[100], tail;
	static int f[] = new int[2000000];
	static int pre[] = new int[2000000];
	
	public static void main(String args[])	throws IOException
	{
		init();
		doit();
	}
	
	static void doit()
	{
		int inf = 100000000;
		for (int i = 0; i <= 1000000; ++ i)	f[i] = inf;
		f[0] = 0;
		pre[0]=-1;
		for (int i = 1; i <= n; ++ i)
		{
			for (int j = 0; j != tail; ++ j)
			{
				if (i - num[j] < 0)	break;
				if (f[i-num[j]] + 1 < f[i])
				{
					f[i] = f[i-num[j]] + 1;
					pre[i] = i-num[j];
				}
			}
			//System.out.println(i+" " + f[i]);
		}
		int now = n;
		int output[] = new int[10000], t=0;
		while (now!=0)
		{
			output[t++]=now-pre[now];
			now=pre[now];
		}
		System.out.println(t);
		for (int i = 0;i!=t;++i)
			System.out.print(output[i]+" ");
		
		
		
	}
	

	
	static void init()	throws IOException
	{
		n = reader.nextInt();
		tail = 0;
		for (int i = 0; i <= 64; ++ i)
		{
			getNum(i);
		}
		/*
		 * debug: 用来输出所有的满足01条件的数字,按顺序
		for (int i = 0; i != tail;++i)
			System.out.print(num[i] +" ");
		*/
	}
	
	static void getNum(int arg)	
	{
		if (arg==0)
		{
			num[tail++]=0;
			return;
		}
		int tmp[]=new int[100];
		int t=0;
		while (arg != 0)
		{
			tmp[t++]=arg%2;
			arg/=2;
		}
		int ret=0;
		for (int i = t-1;i>=0;--i)	ret=ret*10+tmp[i];
		num[tail++]=ret;
	}
	
}

class InputReader
{
	public InputReader() {
		// TODO Auto-generated constructor stub
		tokenizer = new StringTokenizer("");
		reader = new BufferedReader(new InputStreamReader(System.in));
	}
	
	public String nextString()	throws IOException
	{
		while (!tokenizer.hasMoreTokens())
		{
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}
	
	public int nextInt()	throws IOException
	{
		return Integer.valueOf(nextString());
	}
	StringTokenizer tokenizer;
	BufferedReader reader;
}



你可能感兴趣的:(dp,codeforces)