就让我把搜索的题单刷完吧.
这里没有写广搜的做法.
如果用深搜,得要用到一个很有意思的剪枝.
注意这个深搜的状态转移比较独特.
第一次提交
#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了.
也就是说,在搜索过程中如果发现当前状态已经完全地劣于先前发现的解,那么直接结束这次搜索.
这种策略的最坏情况发生在问题为无解时.
这也许是一种常见的剪枝策略吧 ,除此之外我知道的还有标记法.