例题9-3 旅行 UVa1347

1.题目描述:点击打开链接

2.解题思路:本题看似一道几何问题,实际上可以利用动态规划解决。走一圈周长最短可以等价为两个人同时从最左端出发,沿着不同的路径走到最右端。如果定义d(i,j)表示1~max(i,j)全部走过,第一个人在i,第二个人在j,还需要走多长的距离。此时可以规定i>j,这样,还可以规定i,j中只有一个人允许走到i+1这一点。这样的话可以保证不会出现某些点跳过的情况。状态转移方程如下:

d(i,j)=min(d(i+1,j)+dist(i,i+1),d(i+1,i)+dist(j,i+1));

第二项表示为d(i+1,i)是因为已经规定i>j,又根据d(i,j)的定义易知有d(i,j)=d(j,i),因此d(i,i+1)可写为d(i+1,i)。本题的状态数有O(N^2)个,每次状态的决策只有2个,因此时间复杂度为O(N^2)。本题中由于j<i,因此还可以提前计算好所有j<i的距离,这样可以避免重复计算距离,进一步提升效率。

3.代码:

#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<algorithm>
#include<string>
#include<sstream>
#include<set>
#include<vector>
#include<stack>
#include<map>
#include<queue>
#include<deque>
#include<cstdlib>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<ctime>
#include<functional>
using namespace std;

#define maxn 1000+10
struct node
{
	int x, y;
}p[maxn];
int n;
double ans;
double d[maxn][maxn];//表示1到max(i,j)均已经走过,第一个人在i,第二个人在j,还需要走多长的距离
double dist(int i, int j)
{
	int dx = p[i].x - p[j].x;
	int dy = p[i].y - p[j].y;
	return hypot(dx, dy);
}
double dp(int i, int j)
{
	double&ans = d[i][j];
	if (ans > 0)return ans;
	if (i == n - 1)
		return ans = dist(i, n) + dist(j, n);
	ans = min(dp(i + 1, j) + dist(i, i + 1), dp(i + 1, i) + dist(j, i + 1));
	return ans;
}
int main()
{
	//freopen("test.txt", "r", stdin);
	while (scanf("%d", &n) != EOF)
	{
		memset(d, 0, sizeof(d));
		for (int i = 1; i <= n; i++)
		{
			scanf("%d%d", &p[i].x, &p[i].y);
		}
		dp(2, 1);
		ans = dist(1, 2) + d[2][1];
		printf("%.2lf\n", ans);
	}
	return 0;
}
时间: 2024-12-20 18:25:37

例题9-3 旅行 UVa1347的相关文章

动态规划初学

数字三角形: 定义状态(i,j):表示当前所处位置 定义指标函数 d(i,j) :表示从格子(i,j)出发能得到的最大和 找到状态转移方程: d(i,j)=a(i,j)+max{d(i+1,j),d(i+1,j+1)} 总状态为O(n^2),每个状态决策为O(1),总的时间复杂度为O(n^2). 方法:直接递归 缺点:重复计算过多 优化:记忆化搜索 或者: 递推计算(关键 边界和计算顺序) DAG 嵌套三角形: 定义状态(i,j):表示矩形的二元关系,为了通过图来建模? PS:(i)表示从结点i

常用最短路优化算法及例题(附模板)——-SPFA和Dijkstra

常用最短路算法——-SPFA和Dijkstra及其优化 这篇文章将简单讲解两个最常用的最短路优化算法,需要读者有一定的图论基础. 首先从DIJKSTRA讲起.常规的dijkstra算法复杂度较高,为O(n^2),因为要花大量时间来找当前已知的距顶点距离最小的值,所以用优先队列(值小的先出队列)来优化,可大大优化时间复杂度.STL中优先队列的操作单次复杂度为O(logN),所以经过优先队列优化的dijkstra时间复杂度会降到O(N*logN); 以下为核心部分代码: 1 struct pack{

floyd算法--一个人的旅行

2017-07-27 22:37:32 writer:pprp 题目如下: 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰富自己的阅历, 还可以看美丽的风景--草儿想去很多地方,她想要去东京铁塔看夜景,去威尼斯看电影,去阳明山上看海芋,去纽约纯粹看雪景,去巴黎喝咖啡写信, 去北京探望孟姜女--眼看寒假就快到了,这么一大段时间,可不能浪费啊,一定要给自己好好的放个假,可是也不能荒废了训

[BZOJ2388]旅行规划

试题描述 OIVillage是一个风景秀美的乡村,为了更好的利用当地的旅游资源,吸引游客,推动经济发展,xkszltl决定修建了一条铁路将当地n个最著名的经典连接起来,让游客可以通过火车从铁路起点(1号景点)出发,依次游览每个景区.为了更好的评价这条铁路,xkszltl为每一个景区都哦赋予了一个美观度,而一条旅行路径的价值就是它所经过的景区的美观度之和.不过,随着天气与季节的变化,某些景点的美观度也会发生变化. xkszltl希望为每位旅客提供最佳的旅行指导,但是由于游客的时间有限,不一定能游览

acm常见算法及例题

转自:http://blog.csdn.net/hengjie2009/article/details/7540135 acm常见算法及例题 初期:一.基本算法:     (1)枚举. (poj1753,poj2965)     (2)贪心(poj1328,poj2109,poj2586)     (3)递归和分治法.     (4)递推.     (5)构造法.(poj3295)     (6)模拟法.(poj1068,poj2632,poj1573,poj2993,poj2996)二.图算法

HDU2066 一个人的旅行【Dijkstra】

一个人的旅行 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 20569    Accepted Submission(s): 7191 Problem Description 虽然草儿是个路痴(就是在杭电待了一年多,居然还会在校园里迷路的人,汗~),但是草儿仍然很喜欢旅行,因为在旅途中 会遇见很多人(白马王子,^0^),很多事,还能丰

黑书例题 Fight Club 区间DP

题目可以在bnuoj.soj等OJ上找到. 题意: 不超过40个人站成一圈,只能和两边的人对战.给出任意两人对战的输赢,对于每一个人,输出是否可能是最后的胜者. 分析: 首先序列扩展成2倍,破环成链. dp[i][j]表示i和j能够相遇对打,那么dp[i][i+n]为真代表可以成为最后胜者. 枚举中间的k,若i和j都能和k相遇,且i和j至少一人能打赢k,那么i和j可以相遇. 复杂度o(n^3) 1 #include<cstdio> 2 #include<cstring> 3 usi

linux脚本进阶例题解析

例题一:编写脚本/root/bin/createuser.sh,实现如下功能: 使用一个用户名做为参数,如果指定参数的用户存在,就显示其存在,否则添加之:并生成8位随机口令并存在一个文件中,初步提示改口令,显示添加的用户的id号等信息 #!/bin/bash # ------------------------------------------ # Filename: useradd.sh  # Revision: null # Date: 2017-09-11 21:47:22 # Auth

HEOI 2012 旅行问题

2746: [HEOI2012]旅行问题 Time Limit: 30 Sec  Memory Limit: 256 MBSubmit: 1009  Solved: 318[Submit][Status][Discuss] Description yz是Z国的领导人,他规定每个地区的名字只能为26个小写拉丁字母的一个.由于地 区数有可能超过26个,便产生了一个问题,如何辨别名字相同的地区?于是yz规定,一个 地区的描述必须包含它的所有上级,且上级按次序排列.于是,一个地区的描述是一个字符 串.比