uva1347 Tour
uva1347 Tour
题目大意:
两个人同时从最左点出发,沿着两条不同的路径走到最右点(除了起点和终点每个点走且仅走一次)
/* 状态 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]); 第二个走到i+1时本应转移到dp[i][i+1],但是根据此处的规定,必须写成dp[i+1][i] 因为每个点都要走到,所以每次走到没走到的第一个点。 最终结果是 dp[n-1][i]+dist[i][n]+dist[n-1][n];(0<i<n-1) 最终点要走两次。 */ #include<iostream> #include<cstdio> #include<cstring> #include<cmath> using namespace std; int n; double dp[1010][1010],dis[1010][1010]; struct node{ int x,y; }point[1010]; double count(int a,int b){ double x1=point[a].x,x2=point[b].x,y1=point[a].y,y2=point[b].y; return sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)); } int main(){ while(scanf("%d",&n)!=EOF){ for(int i=1;i<=n;i++) scanf("%d%d",&point[i].x,&point[i].y); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ if(i!=j)dis[i][j]=count(i,j); dp[i][j]=0x3fffffff; } dp[1][1]=0; for(int i=1;i<n;i++) for(int j=1;j<n;j++){ dp[i+1][j]=min(dp[i+1][j],dp[i][j]+dis[i][i+1]); dp[i+1][i]=min(dp[i+1][i],dp[i][j]+dis[i+1][j]); } double ans=dp[n][n-1]+dis[n][n-1]; printf("%.2lf\n",ans); } }