迭代加深
DFS在一些问题模型中可能无限扩展,如8数码问题,无限扩展会有些问题,增
加深度限制:假设目标状态所处深度不超过某阈值。人为设定,当搜索深度到达阈
值时直接剪枝,不再往下搜索。
Iterative Deepening Depth - First Search
适用:求最优/深度最低/步数最少解,当问题深度和广度都大的时候
方式:不断放宽迭代深度限制第一次找到的目标状态即为最优解。
迭代加深是深搜和广搜的结合,普通深搜求最优解必须遍历所有状态打擂台得到,
迭代加深后,第一次遇见目标状态即可得到最优解。
深度优先搜索优化-迭代加深(IDDFS)
for(int dep=1;;dep++) { if(dfs(1,dep)) break; }
|
例题1443:【例题4】Addition Chains
n范围较小,初略推出最多十项左右就能得到答案,即答案在搜索树的浅层,可
以使用迭代加深的方法,限制每一次的搜索深度。
例题代码
#include<iostream> #include<cstring> using namespace std; int n,a[105],vis[10005]; bool flag = false;
int dfs(int x,int depth) { if(x>depth) return 0; if(flag==true) return 1; bool vis[5500] = {0}; for (int i = x - 1; i >= 1;i--) { for (int j = i; j >= 1;j--) { int s = a[i] + a[j]; if(vis[s]==1) continue; if(s>n||s<a[x-1]) continue; a[x] = s; vis[s] = 1; if(s==n) { for (int i = 1; i <= x;i++) cout << a[i] << " "; cout << endl; flag = 1; return 1; } dfs(x + 1, depth); } } return 0; }
int main() { while(cin>>n&&n) { memset(a, 0, sizeof(a)); a[1] = 1; flag = false; if(n==1) { cout << 1 << endl; continue; } for (int dep = 2;;dep++) { if(dfs(2,dep)) break; } } }
|
折半搜索
例题P4799 [CEOI2015 Day2]世界冰球锦标赛
例题代码
#include<iostream> #include<algorithm> using namespace std; typedef long long ll; ll pri[55], p1[5000005], ans, n, m, tot;
void dfs1(int x,ll cost) { if (x==(n>>1)+1) { p1[++tot]=cost; return; } if(cost+pri[x]<=m) dfs1(x+1, cost+pri[x]); dfs1(x+1, cost); }
void dfs2(int x,ll cost) { if(x>n) { int l=1, r=tot, add=0; while (l<=r) { int mid=((r-l)>>1)+l; if (p1[mid]+cost<=m) { l=mid+1; add=mid; } else r=mid-1; } ans+=add; return; } if(cost+pri[x]<=m) dfs2(x+1, cost+pri[x]); dfs2(x+1, cost); }
int main() {
cin>>n>>m; for (int i=1;i<=n;i++) cin>>pri[i]; dfs1(1,0); sort(p1+1, p1+1+tot); dfs2(n/2+1,0); cout<<ans; }
|
IDA*
A*与迭代加深的结合使用,通过估价函数计算出递归的层数,若大于当前设定的最大层数,直接剪枝