UVA1347-Tour 双调欧几里得旅行商问题 - 递归记忆实现

来源:互联网 发布:汤灿到底怎么了 知乎 编辑:程序博客网 时间:2024/06/07 18:44

题意:
平面上有n个坐标均为正数的点,按照x坐标从小到大一次给出。求一条最短路线,从最左边的点出发到最右边的点,再回到最左边的点。除了第一个和最右一个点其他点恰好只经过一次。

分析:
可以等效为两个人从第一个点出发,沿不同的路径走到最右点。
d(i, j)表示点1~max(i, j)这些点全部都走过,而且两人的位置分别是i和j,最少还需要走多长的距离。由这个定义可知,d(i, j) == d(j, i),所以我们再加一个条件,d(i, j)中i>j
这样状态d(i, j)只能转移到d(i+1, j)和d(i+1, i)
边界:d(n-1, j) = dist(n-1, n) + dist(j, n) (1 ≤ j < n-1)
原题链接
OJ地址

#include <stdio.h>#include <cstring>#include <iostream>#include <algorithm>#include <cmath>#define RPE(I,A,B) for( int I=(A),_END_=(B);I<=_END_;I++)#define RPED(I,A,B) for( int I=(A),_END_=(B);I>=_END_;I--)#define RP(I,A,B) for( int I=(A),_END_=(B);I<_END_;I++)#define RPD(I,A,B) for( int I=(A),_END_=(B);I>_END_;I--)#define MM(A,V) memset(A,V,sizeof(A))#define pb(X) push_back(X)using namespace std;#define DS(x1,y1,x2,y2) (sqrt(pow((x1)-(x2),2)+pow((y1)-(y2),2)))#define DIST(i,j) DS(x[(i)],y[(i)],x[(j)],y[(j)])#define INF 10000int n;int x[100];int y[100];double d[100][100];double dp(int i,int j) {    double& ans=d[i][j];    if((n-2)==max(i,j)) return DIST(n-2,n-1)+DIST(min(i,j),n-1);    if(ans>0) return ans;        ans=min(dp(i+1,j)+DIST(i,i+1),dp(i+1,i)+DIST(i+1,j));    return ans;}int main() {#define LOCAL#ifdef LOCAL    freopen("uva1347.in","r",stdin);#endif    while(scanf("%d",&n)==1)    {        MM(x,0);        MM(y,0);        MM(d,0);        int i=0;        while(i<n) {            scanf("%d %d",x+i,y+i);            i++;        }        printf("%.2f\n",dp(0,0));    }    return 0;}
0 0
原创粉丝点击