http://poj.org/problem?id=2248
题意:给出一个数n,要求求出最短的一串数字,使其中任意一个数,都可以是任意两个数的和(两个数可以一样),最大的数是n。
做法:当n>2时,就已经可以确定第一个数和第二个数,分别为1和2,然后以后深搜的方式每次都从自身开始向前加,因为这样才能更快的求出最短的一串数字,当发现长度大于已经求得的长度或者现在的值大于所求的值时,便返回上一层,不用继续向下搜。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n,minlen,end[110],temp[110];
void dfs(int pp,int num)
{
int i;
if(pp>minlen||num>n)
return ;
if(num==n)
{
if(pp<minlen)
{
memset(end,0,sizeof(end));
for(i=1;i<=pp;i++)
end[i]=temp[i];
minlen=pp;
return ;
}
}
for(i=pp;i>0;i--)
{
int qq=num+temp[i];
temp[pp+1]=qq;
dfs(pp+1,qq);
}
}
int main()
{
while(scanf("%d",&n)!=EOF)
{
int i;
if(n==0)
break;
if(n==1)
printf("1\n");
else
{
minlen=110;
temp[1]=1;
temp[2]=2;
dfs(2,2);
printf("1");
for(i=2;i<=minlen;i++)
printf(" %d",end[i]);
printf("\n");
}
}
return 0;
}