hdu2224The shortest path 经典问题之 旅行商问题

//平面上有n个点
//问去的路只能从左到右,回的路只能从到右左的且来回必须经过所有点的最小路径
//dp[i][j] 表示以j为起点,1为拐点 ,i为终点的最短路
//j < i-1 时,那么i-1这个点在来的路径上 必然等于dp[i-1][j] + dis[i-1][i] ;
//当j = i -1 ,那么i-1这个点在回的路径上,那么dp[i][j] = min(dp[k][j] + dis[k][j]) 1<=k < j
//可以很容易想到dp[i][j] = dp[j][i] 所以j = i-1时其状态转移方程为dp[i][j] = min(dp[j][k] + dis[k][j]) 1<=k < j

include

include

include

include

using namespace std ;
const int maxn = 210 ;
const int inf = 0x7fffffff ;
double dis[maxn][maxn] ;
double x[maxn] , y[maxn] ;
double dp[maxn][maxn] ;
int main()
{
int n ;
while(~scanf(“%d” , &n))
{
for(int i = 1;i <= n;i++)
{
scanf(“%lf%lf” , &x[i] , &y[i]) ;
for(int j = 1;j < i ;j++)
dis[j][i] = sqrt((x[i] - x[j])(x[i]-x[j]) + (y[i] - y[j])(y[i] - y[j])) ;
}
dp[1][1] = 0 ;
dp[2][1] = dis[1][2] ;
for(int i = 3;i <= n;i++)
{
for(int j = 1;j < i - 1 ;j++)
dp[i][j] = dp[i-1][j] + dis[i-1][i] ;
double mi = inf ;
for(int k = 1;k < i-1;k++)
mi = min(mi , dp[i-1][k] + dis[k][i]) ;
dp[i][i-1] = mi ;
}
dp[n][n] = dp[n][n-1] + dis[n-1][n] ;
printf(“%.2lf\n” , dp[n][n]) ;
}
}

你可能感兴趣的:(dp)