ACcoders Problem 2053 题解

该文介绍了一种寻找最短递增数列的方法,通过迭代加深搜索策略,每次增加深度限制,以保证数列的每个元素最大化。在搜索过程中,倒序枚举元素并检查性质,将符合条件的元素添加到序列中。最终,当序列满足所有条件且最后一个元素为n时,输出该序列。
摘要由CSDN通过智能技术生成

题意

有一数列 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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值