迭代加深搜索(iddfs)

迭代加深搜索(IDDFS)是一种有效的搜索策略,它结合了DFS和BFS的优点,防止搜索过深导致超时,同时也减少了存储状态的需求。这种方法适用于答案层次较浅且搜索树深度增加迅速的问题。在例题POJ2248和UVA529中,IDDFS用于Addition Chains,通过限制搜索深度并逐步加深来找到解决方案。而在POJ3134和UVA1374中,IDDFS被用来进行Power Calculus,即快速幂计算,通过优化搜索顺序和剪枝避免无效计算。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

做法:

从根节点开始 d f s dfs dfs,用一个变量 d e p dep dep限制 d f s dfs dfs的深度,一旦达到 d e p dep dep层,那么就看是否找到目标;如果在 d e p dep dep层没有搜索到目标,那么就将深度的限制 d e p + 1 dep+1 dep+1,继续从根节点重新开始 d f s dfs dfs,如此反复直到找到目标,或者证明目标不存在;

适用于的题目

  1. 能够从题目中推断出答案的层次较浅;
  2. 整个搜索树非常的深而且随着深度的增加,结点增加非常快速;

优势

  1. 相比于dfs,防止一条路走到底,避免超时
  2. 相比于bfs,防止在队列中存储的状态过多,避免超空间;

劣势:

每一次都需要从根节点重新开始搜索,会导致重复;

代码基本框架

bool dfs(int cur)
{
	if (cur==dep)
	{
		return true/false;
	}
	for (cur的邻居)
	{
		ifdfs(next)==true{
			return true;
		}
	}
	return false;
}

int main()
{
	dep=1;
	while (dfs(root)==false)
	{
		dep++;
	}
}

例题:

Sample 1:POJ2248 Addition Chains/UVA529 Addition Chains

思路:
  • 搜索的逻辑,从第1个数开始搜索,对于待搜索的第i项,只可能由1到-1的两个数值加起来得到。

注意,需要剪枝,分别是排除重复以及优化搜索顺序

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
const int maxn=105;
const int INF=0x3f3f3f3f;
int n,dep;
int ans[maxn];
inline int read()
{
	int s=0,f=1;
	char c=getchar();
	while (c<'0'||c>'9')
	{
		if (c=='-')
		{
			f=-1;
		}
		c=getchar();
	}
	while (c>='0'&&c<='9')
	{
		s=(s<<1)+(s<<3)+c-'0';
		c=getchar();
	}
	return s*f;
}
inline void write(int x)
{
	if (x<0)
	{
		x=~(x-1);
		putchar('-');
	}
	if (x>9)
	{
		write(x/10);
	}
	putchar(x%10+'0');
}
inline bool dfs(int cur)							//目前已经在位置1到cur找到结果
{
	if (cur==dep)									//搜索到与 当前迭代的深度的限制相等
	{
		return ans[cur]==n;
	}
	bool vis[maxn]={false};                         //排除重复(剪枝)
	for (int i=cur;i>=1;i--)                        //优化搜索顺序(剪枝)
	{
		for (int j=i;j>=1;j--)						//i,j可以相等
		{
			int num=ans[i]+ans[j];					//和
			if (num<=n&&num>ans[cur]&&vis[num]==false)
			{
				ans[cur+1]=num;
				if (dfs(cur+1)==true)
				{
					return true;
				}
				else
				{
					vis[num]=true;
				}
			}
		}
	}
	return false;
}

int main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	ans[1]=1;
	while (17)
	{
		n=read();
		if (n==0)
		{
			break;
		}
		dep=1;
		while (dfs(1)==false)
		{
			dep++;									//迭代深度
		}
		for (int i=1;i<=dep;i++)
		{
			write(ans[i]);
			printf(" ");
		}
		puts("");
	}
	return 0;
}

Sample 2:POJ3134 Power Calculus/UVA1374 快速幂计算 Power Calculus

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cstdlib>
#include<cmath>
using namespace std;
const int maxn=100005;
const int INF=0x3f3f3f3f;
int n,dep;
int ans[maxn];
inline int read()
{
	int s=0,f=1;
	char c=getchar();
	while (c<'0'||c>'9')
	{
		if (c=='-')
		{
			f=-1;
		}
		c=getchar();
	}
	while (c>='0'&&c<='9')
	{
		s=(s<<1)+(s<<3)+c-'0';
		c=getchar();
	}
	return s*f;
}
inline void write(int x)
{
	if (x<0)
	{
		x=~(x-1);
		putchar('-');
	}
	if (x>9)
	{
		write(x/10);
	}
	putchar(x%10+'0');
}
inline bool dfs(int cur)
{
	if (cur==dep)
	{
		return ans[cur]==n;
	}
	int maxi=-INF;
	for (int i=1;i<=cur;i++)
	{
		maxi=max(maxi,ans[i]);
	}
	if ((maxi<<(dep-cur))<n)
	{
		return false;
	}
	for (int i=cur;i>=0;i--)
	{
		ans[cur+1]=ans[cur]+ans[i];
		if (dfs(cur+1)==true)
		{
			return true;
		}
		ans[cur+1]=ans[cur]-ans[i];
		if (dfs(cur+1)==true)
		{
			return true;
		}
	}
	return false;
}
int main()
{
	//freopen(".in","r",stdin);
	//freopen(".out","w",stdout);
	while (1)
	{
		n=read();
		if (n==0)
		{
			break;
		}
		dep=0;
		ans[0]=1;
		while (dfs(0)==false)
		{
			dep++;
		}
		write(dep);
		puts("");
	}
	return 0;
}
/*
1
31
70
91
473
512
811
953
0
*/
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值