P1135 奇怪的电梯 深度搜索 广度搜索 剪枝

P1135 奇怪的电梯

就让我把搜索的题单刷完吧.

这里没有写广搜的做法.

 P1135 奇怪的电梯 深度搜索 广度搜索 剪枝

如果用深搜,得要用到一个很有意思的剪枝.

注意这个深搜的状态转移比较独特.

第一次提交

#include <algorithm>
#include
<cstdio> #include <cstring> #include <iostream> using namespace std; const int INF = 100000000; int n, A, B, s[210]; long long ans = INF; bool vis[210]; void dfs(int f, long long ct)        // f - 当前所在楼层  ct - 已经按按钮的次数, 也许不需要long long { if(f != B) { if(!vis[f]) { vis[f] = true; if(f + s[f] <= n) dfs(f + s[f], ct + 1); if(f - s[f] >= 1) dfs(f - s[f], ct + 1); vis[f] = false; } }else ans = min(ans, ct); } int main() { cin >> n >> A >> B; for(int i = 1; i <= n; i++) cin >> s[i]; dfs(A, 0); printf("%lld ", ans == INF ? -1 : ans); return 0; }

结果TLE两个点.

而剪枝十分简单,只需要把

  if(f != B)

改成

    if(f != B && ct <= ans)

就可以AC了.


也就是说,在搜索过程中如果发现当前状态已经完全地劣于先前发现的解,那么直接结束这次搜索.

这种策略的最坏情况发生在问题为无解时.

这也许是一种常见的剪枝策略吧 ,除此之外我知道的还有标记法.