Time Limit: 1000MS | Memory Limit: 65536K | |||
Total Submissions: 5067 | Accepted: 2742 | Special Judge |
Description
- a0 = 1
- am = n
- a0 < a1 < a2 < ... < am-1 < am
- For each k (1<=k<=m) there exist two (not necessarily different) integers i and j (0<=i, j<=k-1) with ak=ai+aj
You are given an integer n. Your job is to construct an addition chain for n with minimal length. If there is more than one such sequence, any one is acceptable.
For example, <1,2,3,5> and <1,2,4,5> are both valid solutions when you are asked for an addition chain for 5.
Input
Output
Hint: The problem is a little time-critical, so use proper break conditions where necessary to reduce the search space.
Sample Input
5 7 12 15 77 0
Sample Output
1 2 4 5 1 2 4 6 7 1 2 4 8 12 1 2 4 5 10 15
1 2 4 8 9 17 34 68 77
解題思路:迭代加深搜索即可,注意下一個數k必定等於這個k加上之前得到的數。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,res[20];
int deep;
bool check(int cnt,int num)
{
for(int i = 0; i < cnt; i++)
for(int j = 0; j < cnt; j++)
if(res[i] + res[j] == num)
return true;
return false;
}
bool dfs(int cnt,int num)
{
if(cnt == deep)
{
if(num == n) return true;
return false;
}
for(int i = 0; i <= cnt; i++)
{
num += res[i];
if(num <= n)
{
res[cnt+1] = num;
if(dfs(cnt+1,num)) return true;
}
num -= res[i];
}
return false;
}
int main()
{
while(scanf("%d",&n),n)
{
if(n == 1)
{
printf("1\n");continue;
}
res[0] = 1;
deep = 1;
while(true)
{
if(dfs(0,1)) break;
deep++;
}
for(int i = 0; i <= deep; i++)
printf("%d ",res[i]);
printf("\n");
}
return 0;
}