搜索专题——迭代加深

什么是迭代加深IDDFS?

最通俗的说法,就是限制搜索树层数的DFS
如果当前深度没搜到的话,就加大深度搜索呜呜呜

什么时候用IDDFS呢?

namo,什么时候用IDDFS呢?

即当用BFS时内存会炸掉时,且答案的步数可以预期,且BFS不方便剪枝优化,即使用IDDFS

IDDFS的特点

在这里插入图片描述
引入一些文献呜呜呜:
在这里插入图片描述
在这里插入图片描述

例1:Acwing 170 / POJ 2248

在这里插入图片描述
数据范围: 1 ≤ N ≤ 100 1\le N\le 100 1N100

思路

刚拿到这个题,发现首先不能直接构造,因此需要用搜索来解决问题。
接着就是考虑搜索树的形态,进而考虑是DFS还是BFS…

很明显,本题是构造类型的搜索问题(注意:不是所有的最短问题都容易用BFS做),因此应当选用DFS。

但是问题又出现了,搜索树的深度可能会很深(100+),如果搜索路径偏差了,搜索空间就很大。此时,由上述的思想,迭代加深算法呼之欲出。。。

注意本题的剪枝卡的很死:
1.每一层不要重复访问
2.严格递增
3.不超过n

#include<cstdio>
#include<cstring>
#include<iostream>
#include<cmath>
#include<algorithm>
#include<vector>
#include<string>
#include<set>
#include<map>
#include<queue>

#define me(x,y) memset(x,y,sizeof x)
#define rep(i,x,y) for(i=x;i<=y;++i)
#define repf(i,x,y) for(i=x;i>=y;--i)
#define lowbit(x) -x&x
#define inf 0x3f3f3f3f
#define INF 0x7fffffff
#define LLINF 1e19
#define cu(x) cout<<x<<"--"<<endl
#define ex exit(0)
#define pn puts("")

using namespace std;
typedef long long ll;
typedef pair<int,int> PII;
typedef vector<int> vc;

inline int read()
{
	int x=0,f=1;char ch=getchar();
	while (ch<'0'||ch>'9'){if (ch=='-') f=-1;ch=getchar();}
	while (ch>='0'&&ch<='9'){x=x*10+ch-48;ch=getchar();}
	return x*f;
}

const int N =110;
int n,lim;
bool flag;

int nxt[N];

void dfs(int h)
{
	if(h==lim+1)
	{
		if(nxt[lim]==n)	flag=true;
		return;
	}
	
	int i,j;
	bool st[N];
	me(st,false);
	
	repf(i,h-1,1)
		repf(j,i,1)
		{
			if(nxt[i]+nxt[j]>n)		//超过限制 
				continue;
			if(st[nxt[i]+nxt[j]])	//访问过
				continue;
			if(nxt[i]+nxt[j]<=nxt[h-1])	//不满足递增
				continue;
			
			nxt[h]=nxt[i]+nxt[j];
			st[nxt[h]]=true;
			dfs(h+1); 
			if(flag)	return;
		}
}


int main()
{
	int i,j;
	
	while(scanf("%d",&n),n)
	{
		nxt[1]=1;
		flag=false;
		rep(i,1,n)
		{
			lim=i;
			dfs(2);
			if(flag)
			{
				rep(j,1,lim-1)	printf("%d ",nxt[j]);
				printf("%d\n",nxt[j]);
				break;
			}
		}		
	}

	return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值