poj 2677 双调旅行商dp
来源:互联网 发布:网络侦探 艾克萨 编辑:程序博客网 时间:2024/05/18 02:25
题意:
题意就是双调旅行商。
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.
这种旅程即为从最左点开始,严格地从左到右直至最右点,然后严格地从右到左直至出发点,并且每个x是独一无二的。
然后求最小距离的花费。
解析:
先将坐标按照x轴从小到大排序。
dp[i][j]代表从 i 到 j 的最小花费。
定义从Pi到Pj的路径为:从Pi开始,从右到左一直到P1,然后从左到右一直到Pj。
在这个路径上,会经过P1到Pmax(i,j)之间的所有点且只经过一次。
首先,若 1 <= i < j - 1:
如上图,此时 dp[ i ] [ j ] = dp[ i ] [ j - 1] + dist( j - 1, j )。
这个很好理解,直接到点 1 然后点 1 到 j-1 然后到j的距离。
其次,当 i == j - 1, 1 <= k < j - 1
此时,若还像情况一那样连接的话,点 j-1 和点 j 将会直接连成闭合线,直接忽视n,这种情况不存在。
所以,此时从前面的点1 ~ j - 2 这些点中找到一个满足条件最小的点k, 此时k + 1 ~ j - 2的点全部被放到了下面,然后k直接和点j相连。
即:dp[ i ] [ j ] = dp[ j - 1] [ j ] = min( dp[j - 1] [ k ] + dist(k, j) );
最后再加上闭环 dp[n - 1][n] + dist(node[n - 1], node[n]); 就行了。
代码:
#include <iostream>#include <cstdio>#include <cstdlib>#include <algorithm>#include <cstring>#include <cmath>#include <stack>#include <vector>#include <queue>#include <map>#include <climits>#include <cassert>#define LL long long#define lson lo, mi, rt << 1#define rson mi + 1, hi, rt << 1 | 1using namespace std;const int maxn = 520;const int inf = 0x3f3f3f3f;const double eps = 1e-8;const double pi = acos(-1.0);const double ee = exp(1.0);struct Node{ double x, y;} node[maxn];int n;double dp[maxn][maxn];bool cmp(Node a, Node b){ return a.x < b.x;}double dist(Node a, Node b){ return sqrt((a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y));}double DP(){ dp[1][2] = dist(node[1], node[2]); for (int j = 3; j <= n; j++) { //i < j - 1 for (int i = 1; i < j - 1; i++) { dp[i][j] = dp[i][j - 1] + dist(node[j - 1], node[j]); } // i = j - 1 dp[j - 1][j] = inf; for (int k = 1; k < j - 1; k++) { double t = dp[k][j - 1] + dist(node[k], node[j]); if (t < dp[j - 1][j]) { dp[j - 1][j] = t; } } } return dp[n - 1][n] + dist(node[n - 1], node[n]);}int main(){#ifdef LOCAL freopen("in.txt", "r", stdin);#endif // LOCAL while (~scanf("%d", &n)) { for (int i = 1; i <= n; i++) { scanf("%lf%lf", &node[i].x, &node[i].y); } sort(node + 1, node + n + 1, cmp); printf("%.2lf\n", DP()); } return 0;}
- poj 2677 双调旅行商dp
- poj 2677 Tour(双调欧几里德旅行商问题,dp)
- POJ 2677 Tour 双调旅行商 dp, double+费用流
- POJ 2677 (算法导论15-3)双调欧几里得旅行商问题 dp
- [POJ 2677] Tour 双调旅行商
- POJ 2677 旅行商问题 双调dp或者费用流
- 双调欧几里得旅行商问题 Bitonic_TSP poj 2677
- poj 2677 双调欧几里得旅行商问题
- POJ 2677(双调旅行商问题<bictonicTSP>
- POJ 2677 (双调欧几里德旅行商问题 14.5.29)
- POJ 2677 tour(双调欧几里得旅行商问题)
- poj-2677 动态规划、双调欧几里得旅行商
- POJ 2677 双调欧几里得旅行商问题
- POJ 3311 旅行商问题 状态压缩 dp
- POJ2677 DP tour 双调欧几里得旅行商问题
- CSU 1527 Bounty Hunter dp 双调旅行商
- CSU 1527 - Bounty Hunter(DP‘双调旅行商问题)
- hdu 2224 经典DP 双调旅行商问题
- 矩阵归一化
- Spring和Hibernate整合
- JavaScript常用记录(1)
- ibatis入门例子
- [Linux]打印父进程的所有子进程
- poj 2677 双调旅行商dp
- Java中内部类的内存泄露问题
- 通过学生管理系统项目学到的知识(2)
- 安装ubuntu tweak轻松管理系统
- hadoop优化调整
- LeetCode | Word Break
- FileReader 代码片段
- C++ 声明并实现一个日期类(运算符重载)
- 背包问题教程-01背包,完全背包,多重背包,混合背包 收藏