动态规划

题意可以理解为两个人同时从最左点出发,沿着两条不同的路径走到最右点(除了起点和终点每个点走且仅走一次)

状态 dp[i][j]指当前两人分别走到i,j点。且设i>j;

则有:dp[i+1][i]=min (dp[i+1][i],dp[i][j]+dist[i][i+1]);

     dp[i+1][j]=min (dp[i+1][j],dp[i][j]+dist[j][i+1]);

因为每个点都要走到,所以每次走到没走到的第一个点。

最终结果是 dp[n-1][i]+dist[i][n]+dist[n-1][n];(0<i<n-1) 最终点要走两次。

 

 1 #include <iostream>
 2 #include <algorithm>
 3 #include <cstring>
 4 #include <cstdio>
 5 #include <cmath>
 6 using namespace std;
 7 
 8 const double inf=99999999.0;
 9     int n;
10     double a[1005][2];
11     double dist[1005][1005];
12     double dp[1005][1005];
13 
14 double getdist (double x1,double y1,double x2,double y2){
15     double x,y;
16     x=fabs (x1-x2);
17     y=fabs (y1-y2);
18     return sqrt (x*x+y*y);
19 }    
20 
21 int main (){//cout<<inf<<endl;
22     while (~scanf ("%d",&n)){
23         for (int i=0;i<n;i++){
24             scanf ("%lf%lf",&a[i][0],&a[i][1]);
25         }
26         for (int i=0;i<n;i++)
27             for (int j=0;j<n;j++)
28                 dist[i][j]=getdist (a[i][0],a[i][1],a[j][0],a[j][1]);//cout<<i<<" "<<j<<":"<<dist[i][j]<<"    ";
29         for (int i=0;i<=n;i++)
30             for (int j=0;j<=n;j++)
31                 dp[i][j]=inf;
32         dp[0][0]=0;
33         for (int i=0;i<n-2;i++){
34             for (int j=0;(i==0&&j==0)||j<i;j++){
35                 dp[i+1][j]=min (dp[i+1][j],dp[i][j]+dist[i][i+1]);
36                 dp[i+1][i]=min (dp[i+1][i],dp[i][j]+dist[j][i+1]);//cout<<dp[i+1][j]<<" "<<dp[i+1][i]<<endl;
37             }
38         }//cout<<endl;
39         double ans=inf;
40         for (int i=0;i<n-2;i++)
41             ans=min (ans,dp[n-2][i]+dist[n-1][n-2]+dist[n-1][i]);//cout<<n-2<<" "<<i<<endl,cout<<dp[n-2][i]+dist[n-1][n-2]+dist[n-1][i]<<endl;
42         printf ("%.2f\n",ans);
43     }
44     return 0;
45 }

 

posted on 2014-07-30 09:49  gfc  阅读(382)  评论(0编辑  收藏  举报