Addition Chains ZOJ - 1937

Addition Chains-------(迭代+深搜)

Time limit           2000 ms

Memory limit      65536 kB

题目描述:

An addition chain for n is an integer sequence <a0, a1,a2,...,am> 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.

输入:

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.

输出:

For each test case, print one line containing the required integer sequence. Separate the numbers by one blank.

输入样例:

5
7
12
15
77
0

输出样例:

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

思路解析:

就是要求已知的一个数n,从1变化到n,这个过程需要的最少变化次数mi,a0,a1……ami;这个过程中ai之间的相加方式k=ai+aj,

这里面ai可以等于aj。深搜的过程中只要找到符合最短变化路径的数组即可,答案不唯一。

代码如下:

#include<stdio.h>
int n,mi;
int a[120],s[120];
void dfs(int x,int y)
{
    if(y>mi)    //对于超过前面长度的路径进行返回,没必要再搜下去了
        return;
    if(x==n)    //符合要找的数
    {
        mi=y;   //更新路径长度
        for(int i=0; i<y; i++)    //进行代替
            s[i]=a[i];
        return ;
    }
    for(int i=y-1; i>=0; i--)
    {
        int k=a[i]+x;
        if(k<=n)    //这里显然只有k<=n才满足条件得以继续深搜
        {
            a[y]=k;    //存入数组中
            dfs(k,y+1);    //更改深搜的数,路径加1
        }
    }
}
int main()
{
    while(~scanf("%d",&n)&&n)
    {
        mi=0x3f3f3f;    //因为求最小,初始化为无穷大进行比较
        a[0]=1;   //所有符合输入的开始第一个数都为1,其实第二个也都为2,但是输入的n有可能就是1
        dfs(1,1);      //深搜的前者代表数的更改,后者代表路径大小    
        for(int i=0; i<mi-1; i++)
            printf("%d ",s[i]);
        printf("%d\n",s[mi-1]);
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值