POJ 2248 Addition Chains(DFS)

来源:互联网 发布:mac怎么qq远程控制 编辑:程序博客网 时间:2024/05/29 16:53
Addition Chains
Time Limit: 1000MS Memory Limit: 65536KTotal Submissions: 5218 Accepted: 2810 Special Judge

Description

An addition chain for n is an integer sequence with the following four properties: 
  • 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

The input will contain one or more test cases. Each test case consists of one line containing one integer n (1<=n<=100). Input is terminated by a value of zero (0) for n.

Output

For each test case, print one line containing the required integer sequence. Separate the numbers by one blank. 
Hint: The problem is a little time-critical, so use proper break conditions where necessary to reduce the search space. 

Sample Input

571215770

Sample Output

1 2 4 51 2 4 6 71 2 4 8 121 2 4 5 10 151 2 4 8 9 17 34 68 77

Source

Ulm Local 1997

大概题意:
一个整数n的加法链就是一个满足下面性质的序列:
a0 = 1
am = n
a0 < a1 < a2 < ... < am-1 < am
对于每个k (1<=k<=m) 存在两个整数 (不一定不同) i 和 j (0<=i, j<=k-1) 有ak=ai+aj
你被给定一个n,你的工作是构造一个最短长度的加法链,假设这样的序列超过一个,任何一个合适的序列均可。输入包括很多种测试实例,每个测试实例由一行组成,即就是n,然后输出这个加法链的数字序列。

解题思想:
由于每个数字都是由前面的两个数字之和。并且要使这个数字链最短。那么我们可以深搜一下,假设后面的数是由前面的两个数字的和,前面的两个数是我们可以逐渐往前扫描,那么算符就是前面的两个数相加,得到后面的数,这样深搜下去,并且记录找到解后这个数据链的长度。当数据长度最短时即为所求的解,这里为了加快寻找速度,对于一些不必要搜索的我们不需要去搜索,于是就把它剪去。

#include<stdio.h>using namespace std;int n,len,num[20],ans[20];void dfs(int dep){int i;if(dep > len)   return ;   //剪枝1if(num[dep-1] == n){if(dep < len){len = dep;for(i = 0; i < dep; i++){ans[i] = num[i];}}return ; }   for(i = dep - 1; i >= 0; i--) { num[dep] = num[i] + num[dep-1]; if(num[dep]  > n) { continue;    //剪枝2 }dfs(dep+1);  }} int main(){int i;while(scanf("%d",&n)&&n){len = 11;num[0] = 1;dfs(1);for(i = 0; i < len; i++){printf("%d ",ans[i]);}printf("\n");}return 0;}


0 0
原创粉丝点击