生活就像是与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复杂度的话,就算我会估计也不知道用什么算法,先搁置这个问题.