UVA 1347 Tour [双调欧几里得TSP问题] [dp]

Tour
Time Limit: 3000MS 64bit IO Format: %lld & %llu

Description
Download as PDF
John Doe, a skilled pilot, enjoys traveling. While on vacation, he rents a small plane and starts visiting beautiful places. To save money, John must determine the shortest closed tour that connects his destinations. Each destination is represented by a point in the plane pi = < xi, yi > . John uses the following strategy: he starts from the leftmost point, then he goes strictly left to right to the rightmost point, and then he goes strictly right back to the starting point. It is known that the points have distinct x -coordinates.
Write a program that, given a set of n points in the plane, computes the shortest closed tour that connects the points according to John’s strategy.

Input
The program input is from a text file. Each data set in the file stands for a particular set of points. For each set of points the data set contains the number of points, and the point coordinates in ascending order of the x coordinate. White spaces can occur freely in input. The input data are correct.

Output
For each set of data, your program should print the result to the standard output from the beginning of a line. The tour length, a floating-point number with two fractional digits, represents the result.

Note: An input/output sample is in the table below. Here there are two data sets. The first one contains 3 points specified by their x and y coordinates. The second point, for example, has the x coordinate 2, and the y coordinate 3. The result for each data set is the tour length, (6.47 for the first data set in the given example).

Sample Input
3
1 1
2 3
3 1
4
1 1
2 3
3 1
4 2
Sample Output
6.47
7.89


类似于走两边的方格取数,用dp(i,j)表示第一个人走到i,第二个人走到j的最小值,但是不同的是这个不能重复走到,也就是说取过之后连通性变了,那么改变一下,dp(i,j)表示这种状态且max(i,j)都已经取完的最小值,那么这样不会漏掉某种情况。
转移从两个方向,一个是填表一个是刷表同时进行,分别意味着第一个人去取节点i,以及第二个人,只不过dp(i,j)=dp(j,i) 那么规定 i>=j 才有意义,转移的时候稍微交换一下即可。

#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#ifdef WIN32
#define AUTO "%I64d"
#else
#define AUTO "%lld"
#endif
using namespace std;
#define smax(x,tmp) x=max((x),(tmp))
#define smin(x,tmp) x=min((x),(tmp))
#define maxx(x1,x2,x3) max(max(x1,x2),x3)
#define minn(x1,x2,x3) min(min(x1,x2),x3)
const double INF=1e100;
const int maxn = 1005;
struct Node
{
    int x,y;
}node[maxn];
inline double dist(int i,int j)
{
    int t1=node[i].x-node[j].x;
    int t2=node[i].y-node[j].y;
    return sqrt(t1*t1+t2*t2);
}
int n;
double dp[maxn][maxn];
int main()
{
#ifndef ONLINE_JUDGE
    freopen("tour.in","r",stdin);
    freopen("tour.out","w",stdout);
#endif
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++) scanf("%d%d",&node[i].x,&node[i].y);
        for(int i=1;i<=n;i++)
            for(int j=1;j<=n;j++)
                dp[i][j]=INF;
        dp[1][1]=0.0;
        for(int i=1;i<=n;i++)
            for(int j=1;j1][j]+dist(i-1,i)); // previous determin now
                smin(dp[i][i-1],dp[i-1][j]+dist(j,i)); // now update future , original to be dp[i-1][i] but can change
            }
        double ans = INF;
        for(int j=1;jprintf("%.2lf\n",ans);
    }
    return 0;
}

你可能感兴趣的:(动态规划,常规dp)