P1433 吃乳酪 深度搜索 剪枝 卡時
阿新 • • 發佈:2020-11-29
生活就像是與TLE鬥智鬥勇.
第一次用卡時.
窮竭搜尋,發現情況不如已有解時剪枝.
比較直白的dfs,所以直接放程式碼,重點是裡面用到的一個技巧.
#include <algorithm> #include <cstdio> #include <cstring> #include <iostream> #include <cmath> #include <ctime> using namespace std; int n, t; double ans = 100000000.0; typedef pair<double, double> P; P s[20], tmp; bool used[20]; double len(double x1, double y1, double x2, double y2) { return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2)); } void dfs(double x, double y, double sum) { if(++t > 30000000) { int ti = clock(); if(ti >= 940) { printf("%.2f\n", ans); exit(0); } } if(sum < ans) { bool bad = true; for(int i = 1; i <= n; i++) if(!used[i]) { bad = false; used[i] = true; dfs(s[i].first, s[i].second, sum + len(s[i].first, s[i].second, x, y)); used[i]= false; } if(bad) ans = min(ans, sum); } } int main() { cin >> n; for(int i = 1; i <= n; i++) cin >> s[i].first >> s[i].second; dfs(0, 0, 0); printf("%.2f\n", ans); return 0; }
注意到
if(++t > 30000000) { int ti = clock(); if(ti >= 940) { printf("%.2f\n", ans); exit(0); } }
如果沒有這一段也是完全可以執行的,而且在資料較弱的情況下可以達到時限.
但是這時候TLE了一個點,本地測一下大概需要十秒左右(好像更快一點)才有輸出.可以推測這時候接近於發現的解總是比上一個好的情況,也就是剪枝的最壞情況.
如果懶得換演算法的話,就會用到這種不一定會給出正確答案的方法了,卡時.
在你估計快要超時,但是還沒有搜尋完畢,那就直接給出當前發現的最優解,很有可能就是正確答案.
所以說,這是一種不穩定的方法,可能有的題目會防止卡時讓你爆,但是這題就直接AC了.
如果想要估計dfs複雜度的話,就算我會估計也不知道用什麼演算法,先擱置這個問題.