UVA1347 Tour 双调TSP

TSP是NP难,但是把问题简化,到最右点之前的巡游路线只能严格向右,到最右边的点以后,返回的时候严格向左,这个问题就可以在多项式时间内求出来了。

写的记忆化,懒得想递推顺序。。。

#include<bits/stdc++.h>
using namespace std;

const int maxn = 1001;
int x[maxn],y[maxn];

double dp[maxn][maxn];
bool vis[maxn][maxn];
#define Squ(x) ((x)*(x))

inline double dist(int a,int b)
{
    return sqrt(Squ(x[a]-x[b])+Squ(y[a]-y[b]));
}

int n;
double dfs(int i,int j)
{
    if(vis[i][j]) return dp[i][j];
    vis[i][j] = true;
    if(i == n-1){

        return dp[i][j] = dist(i,n)+dist(j,n);
    }
    return dp[i][j] = min(dfs(i+1,i)+dist(j,i+1),dfs(i+1,j)+dist(i,i+1));
}

int main()
{
   // freopen("in.txt","r",stdin);
    while(~scanf("%d",&n)){
        for(int i = 1; i <= n; i++) scanf("%d%d",x+i,y+i);
        memset(vis,0,sizeof(vis));
        double ans = dfs(1,1);
        printf("%.2lf\n",ans);
    }
    return 0;
}
时间: 2024-08-25 12:20:35

UVA1347 Tour 双调TSP的相关文章

POJ 2677 Tour 双调旅行商 dp, double+费用流

题目链接:点击打开链接 题意:给定二维平面上的n个点 从最左端点到最右端点(只能向右移动) 再返回到到最右端点(只能向左移动,且走过的点不能再走) 问最短路. 费用流: 为了达到遍历每个点的效果 把i点拆成 i && i+n 在i ->i+n 建一条费用为 -inf 的边,流量为1 这样跑最短路时必然会经过这条边,以此达到遍历的效果. dp :点击打开链接 对于i点 :只能跟一个点相连 -- 1.跟 i-1点相连 2.不跟i-1相连 用dp[i][j] 表示两个线头为 i 和 j 的

Chapter_9 DP : uva1347 tour (bitonic tour)

https://cn.vjudge.net/problem/UVA-1347 这道题居然可以O(n^2)解决, 让我太吃惊了!!! 鄙人见识浅薄, 这其实是一个经典问题: bitonic tour. 它的定义是: 从最左点走到最右点在走回来, 不重复经过点, 最小需要多少路程. 在最左点走到最右点的过程中, 只走到比当前点x坐标大的点, 反之同理. (在该题中, 没有两个点x坐标重复) 要得出\(O(n^2)\)的DP算法, 需要几步转化: 首先, 计算从左到右再回来的路径长度很麻烦(因为这样回

UVA 1347(POJ 2677)Tour(双调欧几里得旅行商问题)

Tour                 Time Limit:3000MS    Memory Limit:0KB    64bit IO Format:%lld & %llu Description John Doe, a skilled pilot, enjoys traveling. While on vacation, he rents a small plane and starts visiting beautiful places. To save money, John mus

UVA - 1347 Tour 双调欧几里得旅行商问题

题目大意:给出n个点,要求你从最左边那个点走到最右边那个点,每个点都要被遍历过,且每个点只能走一次,问形成的最短距离是多少 解题思路:用dp[i][j]表示第一个人走到了第i个点,第二个人走到了第j个点且已经遍历了1–max(i,j)的所有点的最短距离.因为dp[i][j] = dp[j][i]的,所以我们设i > j的 那么就有 当j < i-1 时,dp[i][j] = dp[i-1][j] + dis(i, i -1) 当j == i + 1时情况就比较特别了,这里将j用i-1代替 dp

UVA1347---Tour(dp,双调TSP)

dp[i][j]表示在1~max(i,j)都已经被走过的情况下,第一个人在i点,第二个人在j点时,走完剩下的点还需要的最短距离 规定第一个人领先第二个人 所以dp[i][j]可以转移到dp[i+1][j]和dp[i+1][i](等价于dp[i][i+1]) /************************************************************************* > File Name: 平常练习/uva1347.cpp > Author: ALex

UVA1347 Tour

题解: 区间dp DP[i][j],表示1到max(i,j)全部的点都走过,一个落在i,一个落在j点的最小值 规定i>j; 那么当i+1进来时. dp[i][j]--->dp[i+1][i]; dp[i][j]---->dp[i+1][j]; 代码: #include<bits/stdc++.h> using namespace std; #define pb push_back #define mp make_pair #define se second #define f

uva 1347 - Tour(双调欧几里得)

题目大意:给出n个点,确定一条 连接各点的最短闭合旅程的问题. 解题思路:dp[i][j]表示说从i联通到1,再从1联通到j的距离. dp[i][j] = dp[i-1][j] + dis(i,i-1); dp[i][i-1] = min (dp[i][i-1], dp[i-1][j] + dis(i, j)); 记忆化代码: //0 KB 58 ms #include<cstdio> #include<iostream> #include<cstring> #incl

uva 1347 poj 2267 Tour 最短双调回路

// uva1347 Tour 最短双调路线 // 这道题是看着紫书上面写着的 // dp[i][j]表示1至max(i,j)都已经走过时并且第一个人在i // 第二个人在j点时所要走的最短的距离,则dp[i][j] = dp[j][i] // 状态转移方程为 // dp[i+1][j] = max(dp[i][j]+dist[i][i+1],dp[i+1][i]+dist[j][i+1]) // 其实就是考虑第i+1号点是与i相连还是与j相连,(本来dp[i+1][i]是dp[i][i+1]

R语言旅行推销员问题TSP

原文链接:http://tecdat.cn/?p=6551 常用术语中的旅行推销员问题(TSP)是最复杂的问题之一,归结为组合优化.旅行到n个城市(顶点)需要检查(n-1)!可能性.3,000个地点有4 * 10 ^ 9131个可能的解决方案. 本文调查了R包的性能:TSP和tspmeta.结果对我的使用非常满意. 以下代码输入您的TSP225.csv文件并输出您的解决方案和可视化.生成的'tour'对象是一类TOUR和整数;它包含您的解决方案. coords.df <- data.frame(