【洛谷习题】吃奶酪

题目链接:https://www.luogu.org/problemnew/show/P1433


之前还整理过搜索剪枝方面的技巧,但真正做题的时候却想不到。。。

这道题显然可以进行最优性剪枝,当发现现在统计的路径长度比之前求出的可能的答案还要大时,剪枝。当然复杂度比较玄学。个人感觉这题像是TSP问题的弱化版,以后可以尝试用状压DP做一下。

有一个读题方面的细节,题目里说了,坐标是实数,不一定是整数。

 1 #include <cstdio>
 2 #include <cmath>
 3 
 4 const int maxn = 20;
 5 
 6 int n, vis[maxn];
 7 double x[maxn], y[maxn], d[maxn][maxn], ans = 1e9;
 8 
 9 inline double min(double a, double b) {return a < b ? a : b;}
10 
11 inline double pw2(double x) {return x * x;}
12 
13 inline double dis(int i, int j) {
14     return sqrt(pw2(x[i] - x[j]) + pw2(y[i] - y[j]));
15 }
16 
17 void dfs(int i, int last, double sum) {
18     if (i == n + 1) {ans = min(ans, sum);return;}
19     if (sum > ans) return; //最优性剪枝
20     for (int p = 1; p <= n; ++p)
21         if (!vis[p]) {
22             vis[p] = 1;
23             dfs(i + 1, p, sum + d[last][p]);
24             vis[p] = 0;
25         }
26 }
27 
28 int main() {
29     scanf("%d", &n);
30     for (int i = 1; i <= n; ++i) scanf("%lf%lf", &x[i], &y[i]);
31     for (int i = 0; i < n; ++i)
32         for (int j = i + 1; j <= n; ++j)
33             d[i][j] = d[j][i] = dis(i, j);
34     dfs(1, 0, 0);
35     printf("%.2f", ans);
36     return 0;
37 }
AC代码
原文地址:https://www.cnblogs.com/Mr94Kevin/p/9758267.html