uvalive3305(双调欧几里德旅行问题)
2016-05-07 15:10
323 查看
题目大意:
给出坐标是按照x从左到右排序好的,求从最左走到最右再从最右走到最左边的最短路程
思路:
双线性DP。
将一个人从最左端走到最右端,然后从最右端走到最左端等价成两个人同时从最左端不重复的走过中间的点并且到最右端。
我们不妨设这两个人为A和B,且总是假定走在前面的人是A。
再设函数dp(i, j)表示A走到i的位置,B走到j的位置,并且所有i,j之前的位置都被不重复的走过的最短距离之和。
由此得到递推公式:
dp[i+1][i] = min(dp[i+1][i], dp[i][j] + distance(j, i+1));
dp[i+1][j] = min(dp[i+1][j], dp[i][j] + distance(i, i+1));
由于最右节点必然是终点,所以走的快的人必然到达了n点,最终的距离就是枚举i,dp
[i] + distance(i, n)中最小的。
j < i , j 跳到i+1 。
j < i i跳到i + 1
代码:
给出坐标是按照x从左到右排序好的,求从最左走到最右再从最右走到最左边的最短路程
思路:
双线性DP。
将一个人从最左端走到最右端,然后从最右端走到最左端等价成两个人同时从最左端不重复的走过中间的点并且到最右端。
我们不妨设这两个人为A和B,且总是假定走在前面的人是A。
再设函数dp(i, j)表示A走到i的位置,B走到j的位置,并且所有i,j之前的位置都被不重复的走过的最短距离之和。
由此得到递推公式:
dp[i+1][i] = min(dp[i+1][i], dp[i][j] + distance(j, i+1));
dp[i+1][j] = min(dp[i+1][j], dp[i][j] + distance(i, i+1));
由于最右节点必然是终点,所以走的快的人必然到达了n点,最终的距离就是枚举i,dp
[i] + distance(i, n)中最小的。
j < i , j 跳到i+1 。
j < i i跳到i + 1
代码:
#include <iostream> using namespace std; #include <cstring> #include <stdio.h> #include <math.h> const int maxn = 101; struct point { int x,y; }p[maxn]; int n; double dp[maxn][maxn]; double dist[maxn][maxn]; double dis(point p1,point p2) { return sqrt((double)(p1.x - p2.x)*(p1.x - p2.x) + (double)(p1.y - p2.y)*(p1.y - p2.y)); } int main() { while(scanf("%d",&n) != EOF) { for(int i = 0; i < n; i++) scanf("%d%d",&p[i].x,&p[i].y); if(n == 1) { printf("0.00\n"); continue; } for(int i = 0; i < n; i++) { dist[i][i] = 0; for(int j = i + 1; j < n; j++) dist[i][j] = dist[j][i] = dis(p[i],p[j]); } dp[0][0] = 0; for(int i = 1; i < n; i++) dp[i][0] = dist[i][0]; for(int i = 1; i < n - 1; i++) { dp[i + 1][i] = 0x3f3f3f3f;//这里一定要0x3f3f3f3f不可以0x3f for(int j = 0; j <= i - 1; j++) { dp[i + 1][j] = dp[i][j] + dist[i][i + 1]; dp[i + 1][i] = min(dp[i + 1][i],dp[i][j]+dist[j][i + 1]); } } /* double ans = 0X3f;//为什么写这个就WA?? int temp; for(int i = 0; i < n - 1; i++) { if(dp[n - 1][i] < ans) { ans = dp[n - 1][i]; temp = i; } } printf("%.2lf\n",ans + dist[n - 1][temp]);*/ printf("%.2lf\n",dp[n - 1][n - 2] + dist[n - 1][n - 2]); } return 0; }
相关文章推荐
- isset & empty
- 大数据(Big Data)扫盲
- python学习笔记(SMTP邮件发送)
- bzoj4576 [Usaco2016 Open]262144
- Binder学习笔记(四)—— ServiceManager如何响应checkService请求
- hive笔记-----用户定义函数
- 斯坦福大学公开课 编程方法学 Breakout 解题思路
- request.getRequestURI(),request.getRequestURL(),request.getQueryString()区别
- spring-data-mongo-1.8.2.RELEASE连接mongodb副本集备忘
- 二分图匹配(匈牙利算法)
- 从12306信息泄露了解何为黑客撞库拖库洗库
- linux系统中vi/vim 使用方法讲解
- 输入 和 运算符
- js实现上传图片及时预览
- 使用JAVA中的动态代理实现数据库连接池
- .Net 4.5中的HttpClient使用方法
- Objective C中数组排序几种情况的总结
- 读《深度探索C++对象模型》之拷贝构造函数是否有必要明确定义?
- hadoop完全分布式模式的安装和配置
- RBTree(红黑树)--C++