传送门
分析:要求数列中的每个数都有 找最短的数列,没有头绪。既然找最短,就遍历它的数位。这个剪枝真是
妙~~啊
AC代码:
#include<stdio.h>
int n,len;
int a[110];
int dfs(int x)//遍历数组长度
{
int i,j ;
if(a[x-1]==n)
return 1;
if(x>len)//剪枝:长度超了 直接退回去
return 0;
for(i=x-1;i>=1;i--)//从小到大遍历,有利于剪枝
for(j=i;j>=1;j--)
{
if(a[i]+a[j]>n)//剪枝
continue;
if(a[i]+a[j]<a[x-1])//和会一直变小,直接剪掉
break;
a[x]=a[i]+a[j];
if(dfs(x+1))//如果这个数放这个位置不行 可以接着for循环遍历
return 1;
}
return 0;
}
int main()
{
while(~scanf("%d",&n)&&n)
{
a[1]=1;
a[2]=2;
//要求除第一个1外 其他的数都必须是前面一个或两个数的和,所以第二个数必须是2
if(n==1)
{
printf("1\n");
continue;
}
else if(n==2)
{
printf("1 2\n");
continue;
}
else
{
for(len=3;;len++)//限制长度从小到大遍历!!!
{
if(dfs(3))
{
for(int i=1;i<=len;i++)
printf("%d ",a[i]);
printf("\n");
break;
}
}
}
}
}