我是靠谱客的博主 隐形蛋挞,最近开发中收集的这篇文章主要介绍【迭代加深搜索】Addition Chains【迭代加深搜索】Addition Chains,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

【迭代加深搜索】Addition Chains

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 neccessarily 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 file will contain one or more test cases. Each test case consists of one line containing one
integer n (1 ≤ n ≤ 10000). 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.

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

【解析】

一、题目翻译
一个关于整数N的加法链是一个整数序列<A0, A1, …, Am>,满足如下的4个条件:

(1) A0 = 1

(2) Am = N

(3) A0 < A1 < … < Am-1 < Am

(4) 对于每一个k(1 <= k <= m),存在两个整数i和j(0 <= i, j <= m-1且i和j可以相等),使得Ak = Ai + Aj

你的任务是对于给定的N,找出长度最短的加法链,也就是整数序列的个数尽可能少。如果有多个长度相同的方案,输出任意一个方案。

例如,对于N = 5, <1,2,3,5> 和 <1,2,4,5> 都是可行解。

二、解决方法
这道题容易想到用搜索来做,其实也没什么好讲的。我想这道题不同于其他题的特点也就是需要我们去控制搜索时的深度,而这道题的解决方案具体在代码中。

AC代码:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<iostream>
using namespace std;
#define MAXN 10005
int n,dep;
int a[MAXN],p[MAXN];
bool f=0;
void Init()//初始化,以后会用到
{
    int cnt=1;
    p[0]=cnt;
    for(int i=1;i<=20;i++)
    p[i]=(cnt*=2);
}
void print()//输出
{
    for(int i=1;i<dep;i++)
        printf("%d ",a[i]);
    printf("%dn",a[dep]);
}
void dfs(int i)//搜索
{
    if(f) return ;//如果出解便不需要再继续搜索
    if(i==dep)//到达最大的深度
    {
        if(a[dep]==n)//满足最后一个等于n的第一组数据便是解
        {
            f=1;//标记
            print();//输出
        }
        return ;
    }
    else//如果未到达最高点
    {
        for(int k=i;k>=1;k--)//枚举另外一个数(题目要求对于每一个k(1 <= k <= m),存在两个整数i和j(0 <= i, j <= m-1且i和j可以相等),使得Ak = Ai + Aj),当然我们的愿望是尽量的大。
        {
            a[i+1]=a[i]+a[k];
            if(a[i+1]<=n)//满足
            {
                if(a[i+1]*p[dep-i-1]<n) return ;//如果剩下的数我们都选它还不能到达n,愿望破灭。
                dfs(i+1);
                if(f) return ;
            }
        }
    }
}
int main()
{
    a[1]=1;
    a[2]=2;
    Init();
    while(scanf("%d",&n)&&n)
    {
        f=0;
        if(n==1) {printf("1n");continue; }//特判
        for(dep=floor(log2(n))-1;dep<=n;dep++)//控制范围,加快速度
            if(!f) dfs(2);
            else break;
    }
}

最后

以上就是隐形蛋挞为你收集整理的【迭代加深搜索】Addition Chains【迭代加深搜索】Addition Chains的全部内容,希望文章能够帮你解决【迭代加深搜索】Addition Chains【迭代加深搜索】Addition Chains所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(45)

评论列表共有 0 条评论

立即
投稿
返回
顶部