题目
源地址:
http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=4093
理解
给出n个定点,要求计算出连接这些点的最短闭合路径。 使用dp[i][j]来保存从i到1再从1到j的最短距离。然后可以得到这样两条递推公式:
dp[i][i-1]=min(dp[i][i-1],dp[i-1][j]+dis(i,j));
dp[i][j]=dp[i-1][j]+dis(i,i-1);
最后的结果就是遍历一遍dp[n][i]+dis(n,i),找到最小值。
代码
#define MAXN 100+10
int n;
double x[MAXN],y[MAXN],dp[MAXN][MAXN];
double ans;
double dis(int a,int b)
{
return sqrt((x[a]-x[b])*(x[a]-x[b])+(y[a]-y[b])*(y[a]-y[b]));
}
void init()
{
memset(dp,0,sizeof(dp));
dp[2][1]=dis(1,2);
for(int i=1; i<=n; i++)
{
scanf("%lf%lf", &x[i], &y[i]);
}
}
int main(int argc, char const *argv[])
{
while(~scanf("%d", &n))
{
init();
for(int i=3; i<=n; i++)
{
dp[i][i-1]=inf;
for(int j=1; j<i-1; j++)
{
dp[i][i-1]=min(dp[i][i-1],dp[i-1][j]+dis(i,j));
dp[i][j]=dp[i-1][j]+dis(i,i-1);
}
}
ans=inf;
for(int i=1; i<n; i++)
{
ans=min(ans,dp[n][i]+dis(n,i));
}
printf("%.2lf\n",ans);
}
return 0;
}
更新日志
- 2014年11月16日 已AC。