题意:

给定一系列按x坐标升序排列的点,一个人从左向右走到终点再从终点走回起点,要求每个点恰好经过一次,问所走过的最短路径长度。

分析:

可以看成是两个人同时从起点向终点走,且除起点终点外每个点恰有一个人经过。

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.

用d[i][j]表示一个人走到第i个位置,另一个人走到第j个位置时,已经共走了多少距离,规定其中i>j,且1~i全部走过。

题目要求严格按照从左到右和从右到左的顺序,所以不管哪个人下一步只能走i+1,i+2….如果一个人跳过i+1直接走到了i+2,则i+1必将由另一个人走,不妨让走i+1的人先走,这样便保证每次都先走到i+1,得到状态转移方程:(dist数组保存两点之间距离)

dp[i+1][j]=min(dp[i+1][j],dp[i][j]+dist[i+1][i]);
dp[i+1][i]=min(dp[i+1][i],dp[i][j]+dist[i+1][j]);

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=55, INF = 0x3fffffff; //为什么是55?
double x[maxn],y[maxn],dist[maxn][maxn],dp[maxn][maxn];
int main(void)
{
int n;
while(scanf("%d",&n) == 1){
for(int i =0; i < n ; i++)
scanf("%lf%lf",&x[i], &y[i]);
for(int i = 0;i < n; i++)
for(int j = 0 ; j < n ; j++)
dist[i][j] = sqrt((x[i] - x[j]) * (x[i]-x[j]) + (y[i] - y[j]) * (y[i] - y[j])); for(int i = 0; i < n; i++){
for(int j = 0; j < n; j++)
dp[i][j] = INF;
}
dp[1][0]=dist[1][0]; for(int i = 1; i < n - 1; i++) {
for(int j = 0; j < i; j++){
dp[i + 1][j] = min(dp[i + 1][j], dp[i][j] + dist[i + 1][i]);
dp[i + 1][i] = min(dp[i + 1][i], dp[i][j] + dist[i + 1][j]);
}
} double ans = INF;
for(int i = 0; i < n - 1; i++){
ans = min(ans, dp[n-1][i] + dist[n - 1][i]); }
printf("%.2lf\n", ans);
}
return 0;
}

还可以用d[i][j]表示一个人走到第i个位置,另一个人走到第j个位置时,还剩多少距离,则状态转移方程

dp[i][j]=min(dist[i][i+1]+dp[i+1][j],dist[j][i+1]+dp[i+1][i]);  

代码:

#include<cstdio>
#include<iostream>
#include<cstring>
#include<cmath>
using namespace std;
const int maxn=55, INF = 0x3fffffff; //为什么是55?
double x[maxn],y[maxn],dist[maxn][maxn],dp[maxn][maxn];
int main(void)
{
int n;
while(scanf("%d",&n) == 1){
for(int i =0; i < n ; i++)
scanf("%lf%lf",&x[i],&y[i]);
for(int i = 0;i < n; i++)
for(int j = 0 ; j < n ; j++)
dist[i][j] = sqrt((x[i] - x[j]) * (x[i]-x[j]) + (y[i] - y[j]) * (y[i] - y[j])); for(int i = n - 2; i >=1; i--) {
for(int j = i - 1; j >= 0; j--){
if(i == n - 2) dp[i][j] = dist[i][n - 1] + dist[j][n - 1];
else
dp[i][j] = min(dist[i][i + 1]+dp[i + 1][j], dist[j][i + 1] + dp[i + 1][i]);
}
}
printf("%.2lf\n", dist[0][1] + dp[1][0]);
}
return 0;
}

貌似叫双调旅行商问题?

UVA 1347_Tour的更多相关文章

  1. uva 1354 Mobile Computing ——yhx

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABGcAAANuCAYAAAC7f2QuAAAgAElEQVR4nOy9XUhjWbo3vu72RRgkF5

  2. UVA 10564 Paths through the Hourglass[DP 打印]

    UVA - 10564 Paths through the Hourglass 题意: 要求从第一层走到最下面一层,只能往左下或右下走 问有多少条路径之和刚好等于S? 如果有的话,输出字典序最小的路径 ...

  3. UVA 11404 Palindromic Subsequence[DP LCS 打印]

    UVA - 11404 Palindromic Subsequence 题意:一个字符串,删去0个或多个字符,输出字典序最小且最长的回文字符串 不要求路径区间DP都可以做 然而要字典序最小 倒过来求L ...

  4. UVA&&POJ离散概率与数学期望入门练习[4]

    POJ3869 Headshot 题意:给出左轮手枪的子弹序列,打了一枪没子弹,要使下一枪也没子弹概率最大应该rotate还是shoot 条件概率,|00|/(|00|+|01|)和|0|/n谁大的问 ...

  5. UVA计数方法练习[3]

    UVA - 11538 Chess Queen 题意:n*m放置两个互相攻击的后的方案数 分开讨论行 列 两条对角线 一个求和式 可以化简后计算 // // main.cpp // uva11538 ...

  6. UVA数学入门训练Round1[6]

    UVA - 11388 GCD LCM 题意:输入g和l,找到a和b,gcd(a,b)=g,lacm(a,b)=l,a<b且a最小 g不能整除l时无解,否则一定g,l最小 #include &l ...

  7. UVA - 1625 Color Length[序列DP 代价计算技巧]

    UVA - 1625 Color Length   白书 很明显f[i][j]表示第一个取到i第二个取到j的代价 问题在于代价的计算,并不知道每种颜色的开始和结束   和模拟赛那道环形DP很想,计算这 ...

  8. UVA - 10375 Choose and divide[唯一分解定理]

    UVA - 10375 Choose and divide Choose and divide Time Limit: 1000MS   Memory Limit: 65536K Total Subm ...

  9. UVA - 11584 Partitioning by Palindromes[序列DP]

    UVA - 11584 Partitioning by Palindromes We say a sequence of char- acters is a palindrome if it is t ...

随机推荐

  1. [BZOJ1257][CQOI2007]余数之和sum 数学+分块

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1257 题目所求为$$Ans=\sum_{i=1}^nk%i$$ 将其简单变形一下$$Ans ...

  2. mysql提升效率

    1.对查询进行优化,应尽量避免全表扫描,首先应考虑在 where 及 order by 涉及的列上建立索引. 2.应尽量避免在 where 子句中对字段进行 null 值判断,否则将导致引擎放弃使用索 ...

  3. 契约式设计(DbC)感想(二)

    契约式设计6大原则的理解 在<Design by Contract原则与实践>中,作者定义了契约式设计的6大原则: 区分命令和查询: 将基本查询和派生查询区分开: 针对每个派生查询,设定一 ...

  4. JavaScript回文数

    基本解决方案 function palindrome(str) { return str.replace(/[\W_]/g, '').toLowerCase() === str.replace(/[\ ...

  5. 【4412开发板使用经验分享】迅为4412开发板I2C驱动问题

    本文转自迅为论坛:bbs.topeetboard.com 我想写DS3231 的驱动 但是读回的数据老是-6 硬件: 我I2C设备连接的这几个GPIO,看了2.5的手册,接口应该是链接正确的 软件 分 ...

  6. 手机,平板当中浏览和编辑DWG的CAD控件出来啦!支持ARX二次开发

    控件2014.06.30 安卓开发最新更新 发布时间:2014-06-30 22:22:42 开发包下载地址:http://www.mxdraw.com/MxDraw6.0Android(201406 ...

  7. Web应用启动时,后台自动启动一个线程

    (1)前言 前几天,manager问道一个问题:能不能实现类似于cron的后台管理方式.问题解决后,想对这几个问题进行一下简单的总结.以便抛砖引玉!首先简单的提及一下cron. Cron,计划任务,是 ...

  8. Vue+Bootstrap实现购物车程序(1)

    先看下案例效果:(简单的数量控制及价格运算) 代码: <!DOCTYPE html> <html> <head lang="en"> <m ...

  9. 操作iframe的方法

    子页面 <!DOCTYPE html><html lang="en"><head> <meta charset="UTF-8&q ...

  10. 全国绿色计算大赛 模拟赛第一阶段(Python)

    第1关求和 class Task: def getSum(self, num1, num2): sum = 0 for i in range(num1, num2 + 1): while (i != ...