题意:

给定一系列按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. Activiti工作流和shiro权限管理关系图

  2. 30款jQuery常用网页焦点图banner图片切换

    1.jquery 图片滚动特效制作 slide 图片类似窗帘式图片滚动 查看演示 2.jquery幻灯片插件带滚动条的圆形立体图片旋转滚动 查看演示 3.jQuery图片层叠旋转类似洗牌翻转图片幻灯片 ...

  3. Android Studio 导入新工程项目

    1 导入之前先修改工程下相关文件 1.1 只需修改如下三个地方1.2 修改build.gradle文件 1.3 修改gradle/wrapper/gradle-wrapper.properties 1 ...

  4. LoadRunner10自带的WEBTOURS,无法显示Flights页面问题解决办法

    [问题描述] 安装LoadRunner10之后,尝试打开自带的webTours页面学习.第一次可以打开,之后安装了一RFT.Oracle等软件,就出现页面无法显示问题.一直以为是Java的问题,尝试各 ...

  5. Node.js——流的下载

    https://cnodejs.org/topic/59d8f43b2543cb3368b1623e var request = require('request'); var fs = requir ...

  6. numpy基本用法

    numpy 简介 numpy的存在使得python拥有强大的矩阵计算能力,不亚于matlab. 官方文档(https://docs.scipy.org/doc/numpy-dev/user/quick ...

  7. Codeforces Round #460 (Div. 2)_D. Substring_[dp][拓扑排序]

    题意:一个有向图,每个结点 被赋予一个小写字母,一条路径的value等与这条路径上出现次数最多的字母的数目,求该图的最大value 比赛时,用dfs超时,看官方题解用的dp和拓扑排序,a--z用0-2 ...

  8. D. Gourmet choice并查集,拓扑结构

    D. Gourmet choice time limit per test 2 seconds memory limit per test 256 megabytes input standard i ...

  9. 文件描述符 文件操作 <> open 文件句柄

    #! /usr/bin/perl use strict;use warnings; =head1print "\n---------------------------------test_ ...

  10. day02 python函数基础

    '''''''''列表: 定义: 在[]内,可以存放多个任意类型的值, 并以逗号隔开. 一般用于存放学生的爱好,课堂的周期等等...'''# 定义一个学生列表,可存放多个学生# list(['钱垚', ...