POJ 2677 Tour DP

双调欧几里得问题,复习一下。。

把所有的点按照x排序,设计状态f(i,j)表示走在前面的那个走到了i点,后面那个在j点,所需的最小,那么转移显而易见。

f(i,j) = min(f(i - 1,j) + dist(i,i - 1), f(i,i - 1) + dist(i,j))

直接顺着推过去可能好理解一些。。

当前状态f(i,j) 如果由i走到i + 1,那么就是f(i + 1,j),否则就是f(i + 1,i)..

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <bitset>
#include <list>
#include <cstdlib>
#include <climits>
#include <cmath>
#include <ctime>
#include <algorithm>
#include <stack>
#include <sstream>
#include <numeric>
#include <fstream>
#include <functional>

using namespace std;

#define MP make_pair
#define PB push_back
typedef long long LL;
typedef unsigned long long ULL;
typedef vector<int> VI;
typedef pair<int,int> pii;
const int INF = INT_MAX / 3;
const double eps = 1e-8;
const LL LINF = 1e17;
const double DINF = 1e60;
const int maxn = 500;

struct Point {
    double x,y;
    Point(double x = 0,double y = 0): x(x), y(y) {}
    bool operator < (const Point &p) const {
        if(fabs(p.x - x) < eps) return y < p.y;
        return x < p.x;
    }
};

double sq(double x) { return x * x; }

int n;
double f[maxn][maxn];
Point p[maxn];
double dist[maxn][maxn];

int main() {
    while(scanf("%d",&n) != EOF) {
        for(int i = 1;i <= n;i++) {
            scanf("%lf%lf",&p[i].x,&p[i].y);
        }
        for(int i = 1;i <= n;i++) {
            for(int j = 1;j <= n;j++) {
                f[i][j] = DINF;
            }
        }
        sort(p + 1, p + 1 + n);
        for(int i = 1;i <= n;i++) {
            for(int j = 1;j <= n;j++) if(i != j) {
                dist[i][j] = sqrt(sq(p[i].x - p[j].x) + sq(p[i].y - p[j].y));
            }
        }
        double ans = DINF;
        f[1][1] = 0;
        for(int i = 1;i <= n;i++) {
            int m = i == 1 ? 1 : i - 1;
            for(int j = 1;j <= m;j++) {
                f[i + 1][i] = min(f[i + 1][i], f[i][j] + dist[j][i + 1]);
                f[i + 1][j] = min(f[i + 1][j], f[i][j] + dist[i][i + 1]);
                if(i == n) {
                    ans = min(ans, f[i][j] + dist[j][n]);
                }
            }
        }
        printf("%.2f\n",ans);
    }
    return 0;
}

  

时间: 2024-08-05 11:10:52

POJ 2677 Tour DP的相关文章

POJ 2677 Tour 双调旅行商 dp, double+费用流

题目链接:点击打开链接 题意:给定二维平面上的n个点 从最左端点到最右端点(只能向右移动) 再返回到到最右端点(只能向左移动,且走过的点不能再走) 问最短路. 费用流: 为了达到遍历每个点的效果 把i点拆成 i && i+n 在i ->i+n 建一条费用为 -inf 的边,流量为1 这样跑最短路时必然会经过这条边,以此达到遍历的效果. dp :点击打开链接 对于i点 :只能跟一个点相连 -- 1.跟 i-1点相连 2.不跟i-1相连 用dp[i][j] 表示两个线头为 i 和 j 的

[ACM] POJ 2677 Tour (动态规划,双调欧几里得旅行商问题)

Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3585   Accepted: 1597 Description 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

UVA 1347(POJ 2677)Tour(双调欧几里得旅行商问题)

Tour                 Time Limit:3000MS    Memory Limit:0KB    64bit IO Format:%lld & %llu Description John Doe, a skilled pilot, enjoys traveling. While on vacation, he rents a small plane and starts visiting beautiful places. To save money, John mus

UVA 1347(POJ 2677) Tour(双色欧几里德旅行商问题)

Description 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 r

poj 2677 Tour

Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 4556   Accepted: 1993 Description 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

POJ 2677 旅行商问题 双调dp或者费用流

Tour Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 3408   Accepted: 1513 Description 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

poj 3342(树形dp)

题意:在一个公司中要举办一个聚会,每一个员工有一个奉献值.为了和谐规定直接上下级不能一起出席.让你找出奉献值之和最大为多少. 思路:dp[v][1]表示当前结点选,能获得的最大奉献值,dp[v][0]表示当前节点不选能获得的最大奉献值.状态转移: dp[v][0] = max(dp[v][0], ∑max(dp[x][1], dp[x][0]))x为直接儿子 dp[v][1] = max(dp[v][1], ∑dp[x][0] + vex[v]) 最后答案是max(dp[root][0], dp

poj 2151 概率dp

//poj 2151 概率dp 1 #include "iostream" 2 #include "cstdio" 3 #include "cstring" 4 #include "algorithm" 5 using namespace std; 6 double dp[33][33]; 7 int M, T, N; //problem, team, least 8 double p[1010][33]; 9 int mai

POJ 2250 Compromise (DP,最长公共子序列)

Compromise Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6440 Accepted: 2882 Special Judge Description In a few months the European Currency Union will become a reality. However, to join the club, the Maastricht criteria must be fulfille