UVA

来源:互联网 发布:淘宝排名突然下降 编辑:程序博客网 时间:2024/05/29 18:57

题目描述:

点击打开链接

题意给你一系列的点,输入保证x升序,一个人从左到右在从右走回左边,出终点和起点以外,每个点走且仅走一次。

每个点一次且仅一次的这个条件其实也为我们提供了一定的便利,既然这样,那么完全可以处理成两个人同时从左边出发走到右边,并且走的路径不同,那么我们就需要把每个点都遍历一遍,我为了方便操作我们认为总有一个人走的快而另一个人慢即j<i,设计状态为dp[i][j]为快的人走到i慢的人走到j时的最短路程,然后遍历即可。

AC代码:
#include<iostream>#include<cstdio>#include<cstring>#include<cmath>#include<string>#include<stack>#include<queue>#include<algorithm>using namespace std;const int INF=9999999;struct node{    double x,y;};struct node p[110];double dp[110][110];int n;double dis(struct node n1,struct node n2){    double s=sqrt((n1.x-n2.x)*(n1.x-n2.x)+(n1.y-n2.y)*(n1.y-n2.y));    return s;}int main(){    while(scanf("%d",&n)!=EOF)    {        for (int i=1;i<=n;i++)            scanf("%lf%lf",&p[i].x,&p[i].y);        memset(dp,INF,sizeof(dp));        dp[2][1]=dis(p[1],p[2]);        for (int i=1;i<=n;i++)        {            for (int j=1;j<i;j++)            {                dp[i+1][i]=min(dp[i+1][i],dp[i][j]+dis(p[i+1],p[j]));                dp[i+1][j]=min(dp[i+1][j],dp[i][j]+dis(p[i+1],p[i]));            }        }        double ans=INF;        for (int i=1;i<=n;i++)            if (dp[n][i]+dis(p[n],p[i])<ans)            ans=dp[n][i]+dis(p[n],p[i]);        printf("%.2lf\n",ans);    }    return 0;}