迭代加深搜索

题目描述

一个与 nn 有关的整数加成序列 <a_0,a_1,a_2,...,a_m><a0,a1,a2,...,am> 满足以下四个条件:
1.a_0=11.a0=1
2.a_m=n2.am=n
3.a_0<a_1<a_2<...<a_{m-1}<a_m3.a0<a1<a2<...<am1<am
4.4. 对于每一个 k(1≤k≤m)k(1km) 都存在有两个整数 ii 和 j(0≤i,j≤k-1,ij(0i,jk1,i 和 jj 可以相等 )) ,使得 a_k=a_i+a_jak=ai+aj
你的任务是:给定一个整数 nn ,找出符合上述四个条件的长度最小的整数加成序列。如果有多个满足要求的答案,只需要输出任意一个解即可。
举个例子,序列 <1,2,3,5><1,2,3,5> 和 <1,2,4,5><1,2,4,5> 均为 n=5n=5 时的解。

输入格式

5
7
12
15
77
0

输入包含多组数据。每组数据仅一行包含一个整数 n(1≤n≤10000)n(1n10000) 。在最后一组数据之后是一个 00 。

输出格式

 

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

未完成代码:

#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=1e4+5;
int n,ans[maxn],now[maxn];
bool vis[maxn],fd;
void dfs(int dep,int limit)
{
if(!fd)return;
printf("deep:%d lmt:%d\n",dep,limit);


for(int i=1;i<dep;i++){
for(int j=i;j<dep;j++){
int val=now[i]+now[j];
// printf(" %d ",val);
if(!vis[val]){
vis[val]=1;
now[dep]=val;

if(val==n){
// printf("now=%d ",dep);
// putchar('*');
fd=0;
for(int i=2;i<=dep;i++){
ans[i]=now[i];
printf(" %d ",i);
}
return;
}
if(dep==limit)return;
else {

dfs(dep+1,limit);

}
}
}
}
}
int main()
{
while(scanf("%d",&n) && n){
//memset(vis,0,sizeof(vis));
int deep=2;
ans[1]=now[1]=1;
vis[1]=1;
do{
memset(vis,0,sizeof(vis));
fd=1;
dfs(2,deep);
deep++;
//return 0;
}while(fd);
for(int i=1;i<deep;i++){
printf("%d ",ans[i]);
}
putchar('\n');
}
return 0;
}

#include<cmath>
#include<cstdio>
#include<vector>
using namespace std;
const int MAXN=10000;
int vec[MAXN+5]={1},depth,n,p[MAXN+5]={0,1};
bool dfs(int x)
{
    if(x==depth)
    {
        if(vec[x-1]==n) return true;
        return false;   
    }
    int i=x-1;
    for(int j=i;j>=0;j--)
        if(vec[i]+vec[j]>vec[x-1])
        {
            if(vec[i]+vec[j]>n) continue;
            vec[x]=vec[i]+vec[j];
            int sum=vec[x];
            sum*=p[depth-x];
            if(sum<n) return false;
            if(dfs(x+1)) return true;
        }
        else break;
    return false;
}
int main()
{
    for(int i=2;i<=MAXN;i++) p[i]=1<<(i-1);
    while(scanf("%d",&n) && n)
    {
        if(n==2) {printf("1 2\n");continue;}
        depth=(int)log2(n);
        while(1)
        {
            if(dfs(1))
            {
                printf("1");
                for(int i=1;i<depth;i++) printf(" %d",vec[i]);
                printf("\n");
                break;
            }
            depth++;
        }
    }
    return 0;
}

 

#include<cstdio>
#include<iostream>
#include<cstdlib>
#include<cstring>
using namespace std;
int n,ans[105],now[105],deep;
bool vis[105],judge;
inline void print(int dep){
    for(int i=1;i<=dep;i++)printf("%d ",now[i]);
    putchar('\n');
}
void dfs(int dep,int limit){
    if(dep==limit+1)return;
    //printf("deep=%d\n",deep);
//printf("dep%d lim%d:\n",dep,limit);
//print(dep-1);

    for(int wt=dep-1;wt>=1;--wt){
    for(int i=wt;i;i--){
        int val=now[wt]+now[i];
        
        if(val>now[dep-1] && val<101){
        //printf("value%d\n",val);
//            vis[val]=1;
            now[dep]=val;
        
        if(val==n){
            judge=0;
            for(int j=1;j<=dep;j++){
            ans[j]=now[j];
            }
            return;
        }
        
        if(dep==limit)continue;
        else {dfs(dep+1,limit);if(!judge)return;}
        }
    }    
    }
    
    
}

int main()
{
    ans[1]=now[1]=1;
    
    while(scanf("%d",&n) && n)
    {
        //printf("%d",n);
        if(n<4){
for(int i=1;i<=n;i++)printf("%d ",i);
putchar('\n');
continue;
        }
        deep=1;
        judge=1;
        do{
        deep++;
        dfs(2,deep);
        }while(judge);
        //putchar('1');
        for(int k=1;k<deep;k++){
        printf("%d ",ans[k]);    
        }
        printf("%d ",n);
        printf("\n");
    }
    return 0;
}

 

posted @ 2019-04-02 00:43  Tj1  阅读(453)  评论(0编辑  收藏  举报