加成序列(迭代加深dfs)

题目描述:

满足如下条件的序列X(序列中元素被标号为1、2、3…m)被称为“加成序列”:

1、X[1]=1

2、X[m]=n

3、X[1]<X[2]<…<X[m-1]<X[m]

4、对于每个 kk(2≤k≤m2≤k≤m)都存在两个整数 ii 和 jj (1≤i,j≤k−11≤i,j≤k−1,ii 和 jj 可相等),使得X[k]=X[i]+X[j]。

你的任务是:给定一个整数n,找出符合上述条件的长度m最小的“加成序列”。

如果有多个满足要求的答案,只需要找出任意一个可行解。

输入格式

输入包含多组测试用例。

每组测试用例占据一行,包含一个整数n。

当输入为单行的0时,表示输入结束。

输出格式

对于每个测试用例,输出一个满足需求的整数序列,数字之间用空格隔开。

每个输出占一行。

数据范围

1≤n≤1001≤n≤100

输入样例:

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

这道题目,你首先可以明确地算出,最终m的长度必然是小于10的.这就是迭代加深的精髓所在,就是我们确定答案在一个比较浅的位置.

我们可以推出在20以上的数,统统都是m>6的,而50以上的,除了64统统都是大于7的,这就是我们玄学数学优化,特别加速.

优化搜索顺序:我们要让序列中的数字迅速地逼近N,自然是要i和j从大到小枚举,且j<=i,一定要注意这一点,不然你就会TLE,而且特别卡常.

排除等效冗余:我们发现,对于不同的i和j,他们的X[i]+X[j]有一定的可能性会相同,所以避免重复搜索,我们需要进行判重.

AC代码:

/*

                                  MMM
                                MMMMMMM:
                               ~MM    MMM
                               7M+     MM
                                MM
                    MMMMMM,     MM      MM                   ,,:+MMM:
                   MMM   MMM    MM~     MM    ~MMMMMMMMMMMMMMMMMMMMMMM$
                  ZM$     MMM    MM     MMMMMMMMMN          MMM      MMM$
                  MM       MM8    MM OMMMMMO                MM         MM~
                  ,MM       MM   ,MMMMM MM     MMMMMMZ     ,MM          MMM
                   MM?       MMDMMMMM+ ,      MM    MM,    ~MD        ,  MM
                    MM8     :MMMO    IMMM,   MMÁÁÁÁ  MM    MM  MMM ,MMO  MM
                     MMM   MMMMM    MMMMMMM  MM      M8    MM  MMM  MM   NM
                      MMMMMM       MM    ~MM  MM7   MM      MM7           DM
                       7MMM       MM ÁÁÁÁ MM   MMMMMM       MM?          MM
                      MMM M       MM      MM                  MMD        :MM
                     MMM          MMM   IMM                    NMMM     IMM
                    NMM            7MMMMMM                       MMMMMMMMM
                                                                   MMM
                   MM                                               MMM
                  MM     DMM?                                     MMM:
                 7MM  MMMMMMMMMM                               MMMM
                 MM  MMM      MMMN                        MMMMMM7
                 MM  MM         MMD                     MMMMM
                DM~  MM          MM                        MM
                NM   MM          MM                        MM=
                MM   MM          NM                         MM
                NM   +MM         MM                   NM    MM
                OM?   MMM       8MM                  ,MM    ZMZ
                 MM    MMMM   :MMM   +?              MMM     MM
                 MM      MMMMMMM:    MM             =MM     +MM
                 MM:                  MMM          MMM      MM
                  MM                   MMMMMMMMMMMMM?       MM
                  MM+                     ?MMMMM$          MM7
                   MM                                      MM
                    MM                                    MM
                    =MM                                 ZMM
                      MMM                             MMMM
                     ~MMMMM                         MMMMMM
                     MM  ?MMMM                   8MMMM   MM
                    MM      MMMMMMN,         NMMMMM      ,MM
                  ZMM           =MMMMMMMMMMMMMM           DMM
            ,MMMMOMM8                                      MM7MMMM
 MMM?    MMM,   MMMM                                       ,MMM   +MMM     MMM
MM   MMMM   7MMM MM                                         MM ?MMM   8MMM8   M
 :MMM    NMM~    MM                                          MM    MMM    MMMM
  MO   MM       MM                                            MM      DMI  ?ND
~M,ZMNIM        MM                                            8MM     :M M$ MM
 MM            MM                                              MM      MOM8MMM
     ~         MM                                               MM         D
              OM?                                               ~MM
       MMMM   MM                                                 MM
      M MM M= MM                                                =MM
  MM M~MMMMNMMN                                                  MN
 M M,MM+M?MM                                                     MM
  MNOMMM ,,NDMM                                                  MM
            MMM                                                  MM
            MM                                                   MM
            +M$                                                  MM
            MM                                                   MM
            MM                                                   MM
            MMMMMMMMMMMMMMMMMMMMMMMMMMNNNNNNDDZZZZIIIIIIIZZZDNMMMMM
            ,  :~IZ8DNMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMMN
                        NM MZ                  MM M
                        NM M7                  MM7M
                        NM M+                  MMDM
                        DM M=                  MMMM
                        DM M                   MMMM     ZM=
                        DMMMMMMMMMMMMN         MMMMMMMMMMMMM=
                        MM          MM         MM          MM
                        ~MMMMMMMMMMMM8         +MMMMMMMMMMMM
*/
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<vector>
#include<stdlib.h>
#include<queue>
#include<map>
#include<iomanip>
#include<math.h>
const int INF = 0x3f3f3f3f;
using namespace std;
typedef long long ll;
typedef double ld;
int i,j,k,l;
int n,s;
int x[110];
int sum[110];
int dfs(int now,int deep,int last)
{//当前now深度,deep最大深度,
    //last为上一次的数值,我们要满足数列的单调递增性.
    if (x[now]==n)//找到了
        return now;
    if (now>=deep)//超过深度
        return 0;
    for(int i=now; i>=1; i--)
        for(int j=i; j>=1; j--)
            if(!sum[x[i]+x[j]]&&x[i]+x[j]>=last)
            {
                x[now+1]=x[i]+x[j];
                sum[x[i]+x[j]]=true;
                int sm=dfs(now+1,deep,x[i]+x[j]);
                if(sm)
                    return sm;
                sum[x[i]+x[j]]=false;
                x[now+1]=0;
            }
            else if(!sum[x[i]+x[j]])
                break;
    return 0;
}

int main()
{
    while(~scanf("%d",&n)&&n)
    {
        x[1]=1;
        x[2]=2;
        k=n;
        if (n>2)
        {
            if (n>20)
                k=6;
            else
                k=3;
            for(; k<=10; k++)
            {
                memset(sum,0,sizeof sum );
                memset(x,0,sizeof x);
                x[1]=1;
                x[2]=2;
                s=dfs(2,k,3);
                if(s!=0)
                    break;
            }
        }
        for(i=1; i<k; i++)
            printf("%d ",x[i]);
        printf("%d\n",x[k]);
    }
    return 0;
}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值