UVa 1347 旅行

 https://vjudge.net/problem/UVA-1347

思路:用d(i,j)表示第一个人走到i,第二个人走到j,还需要走多长的距离。在这里强制定义i>j,并且每次只能走到i+1。

       状态转移方程为:d(i,j)=min(d(i+1,j)+dist(i,i+1),d(i+1,i)+dist(j,i+1)); 

       仿照紫书“硬币问题”的代码,可以写成如下形式:

 1 #include<iostream> 
 2 #include<cstring>
 3 #include<algorithm>
 4 #include<cmath>
 5 using namespace std;
 6 
 7 const int maxn=1000+5;
 8 
 9 int n;
10 
11 struct node
12 {
13     int x, y;
14 }a[maxn];
15 
16 double d[maxn][maxn];   //第一个走到i,第二个人走到j,d[i][j]表示此时还需要走多长的距离
17 
18 
19 double dist(int i,int j)
20 {
21     int dx = a[i].x - a[j].x;
22     int dy = a[i].y - a[j].y;
23     return hypot(dx, dy);  //计算直角三角形的斜边
24 }
25 
26 double dp(int i, int j)  //i一定大于j
27 {
28     double& ans = d[i][j];
29     if (ans > 0)  return ans;
30     if (i == n - 1)
31         return ans=dist(i, n) + dist(j, n);
32     ans = min(dp(i + 1, j) + dist(i + 1, i), dp(i + 1, i) + dist(i + 1, j));
33     return ans;
34 }
35 
36 int main()
37 {
38     //freopen("D:\txt.txt", "r", stdin);
39     while (cin >> n && n)
40     {
41         memset(d, 0, sizeof(d));
42         for (int i = 1; i <= n; i++)
43         {
44             cin >> a[i].x >> a[i].y;
45         }
46         dp(2, 1);
47         double ans = dist(2, 1) + d[2][1];
48         printf("%.2f
", ans);
49     }
50     return 0;
51 }
原文地址:https://www.cnblogs.com/zyb993963526/p/6358333.html