UVA

来源:互联网 发布:为知笔记 vip 编辑:程序博客网 时间:2024/04/28 13:01

题目地址:点击 UVA 1347 链接


样例输入: 

3

1 1

2 3

3 1

4

1 1

2 3

3 1

4 2

样例输出:

6.47 

7.89


题意:  给你n个点  你的任务是求出从最左边点到最右边点 再从最右边点 回来的最短路径  (要求没个点都要走一遍)    。。

思路: dp[i][j]   我们假设同时有两个人在走  那么,两个人走的 路径不同 ,但是尽量短的走 ,那么走到两个人都走到第n个点,就会出现一个最短路径。我们假设两个人的当前位置分别是 i 和 j  那么dp[i][j]  看可以转移到  dp[i+1][j] 和 dp[i+1][i]  两种状态。分别表示  i 走到i+1  和 j  走到  i+1  个点。。 (注意  j 走到i+1  本应该转移到dp[i][i+1]  但是 我们 规定  i>j  其实也是为了 更好的去求解。 )  

那么初始状态  就是dp[n][i](i>=1&&i<=n)  dp[n][i]=dis[n][i];  

那么状态转移方程我们也可以很好的推出来  因为dp[i][j] 可以转移到dp[i+1][j]  和dp[i+1][i]  两种状态 ,那么dp[i][j] 的状态当然也是由  dp[i+1][j]  he dp[i+1][i] 两种状态倒着退回来 。  dp[i][j]=min(dp[i+1][j]+dis[i+1][i],dp[i+1][i]+dis[j][i+1])


代码: 


#include<stdio.h>#include<string.h>#include<math.h>#include<iostream>#include<algorithm>#define N 1005using namespace std;double dp[N][N];double dis[N][N];struct node{int x,y;}a[N];int n;double juli(int i,int j){int x,y;double fin;x=abs(a[i].x-a[j].x);  y=abs(a[i].y-a[j].y);fin=x*x+y*y;return sqrt(fin);}void memdp(){for(int i=1;i<=n;i++) dp[n][i]=dis[n][i];for(int i=n-1;i>=1;i--){for(int j=1;j<=i;j++){dp[i][j]=min(dp[i+1][j]+dis[i+1][i],dp[i+1][i]+dis[j][i+1]);}}printf("%.2f\n",dp[1][1]);return ;}void chushihua(){for(int i=0;i<=n;i++){for(int j=0;j<=n;j++){dp[i][j]=dis[i][j]=0.0;}}return ;}int main(){while(cin>>n){for(int i=1;i<=n;i++) cin>>a[i].x>>a[i].y;chushihua();for(int i=1;i<=n;i++){for(int j=1;j<=n;j++){double dist=juli(i,j);dis[i][j]=dist;}}memdp();}return 0;}


原创粉丝点击