题意
有一数列 a a a,其中第一位为 1 1 1,最后一位为 n n n,满足单调递增的性质,对于每一个 a k a_{k} ak 都有一个 a i + a j a_{i}+a_{j} ai+aj 与它相等。求长度最短的满足上述所有条件的序列。
思路
考虑迭代加深搜索,每次限制一个深度 d e p dep dep,每次将其 + 1 +1 +1,限制其搜索的深度,直到找到合法第一个答案,长度即为当前深度,也就是本题的最短序列。
因为要使这个序列最短,所以我们也就要使其每个元素最大,尽可能的满足其性质,所以我们倒叙枚举 i i i 和 j j j,从而得出 a k a_{k} ak。
如果当前得到的 k k k 再我们构造的序列中没有出现过且合法(单调递增),我们又可以构造出一个标记数组,如果它再我们当前的序列里,就将其打上标记。将我们枚举到的 k k k 放入序列。
最后,如果深度到了我们限制的 d e p dep dep,就看当前此序列是否合法。因为除了最后一位是否为 n n n 的性质我们都已经检验过了,所以最后一位如果为 n n n,就说明已经构造出了满足所有要求的序列,直接输出即可。
代码
#include<bits/stdc++.h>
using namespace std;
int ans[10001];
int dep,n;
bool dfs(int u)
{
if(u>dep) return 0;
if(u==dep)
return ans[u]==n;
bool vis[10001]={0};
for(int i=u;i>=1;i--)
for(int j=i;j>=1;j--)
{
int k=ans[i]+ans[j];
if(k<=n&&!vis[k]&&k>ans[u-1])
{
ans[u+1]=k;
vis[k]=1;
if(dfs(u+1)) return 1;
}
}
return 0;
}
int main()
{
while(~scanf("%d",&n)&&n)
{
ans[1]=dep=1;
while(!dfs(1)) dep++;
for(int i=1;i<=dep;i++)
printf("%d ",ans[i]);
puts("");
}
return 0;
}