HDU 4824 双调旅行商问题

由于跳转一次需要400,大于在扇道内转一圈,所以应尽可能少的跳转扇道,就转换成了双调旅行商问题,

即从0区开始访问到最大的区域,再返回0区,所有中间点需走到一次

#include "stdio.h"
#include "string.h"
#include "math.h"
#include "algorithm"
using namespace std;
struct node
{
    int x,y;
}a[1010];

int Abs(int a)
{
    if (a<0) return -a;
    else return a;
}

bool cmp(node a,node b)
{
    if (a.x!=b.x) return a.x<b.x;
    else return a.y<b.y;
}

int n;
int inf=0x3f3f3f3f;

int dis[1010][1010],dp[1010][1010];

int cal(int i,int j)
{
    int temp,mark;
    temp=0;
    if (a[i].x!=a[j].x)
        temp+=Abs(a[i].x-a[j].x)*400;
    mark=Abs(a[i].y-a[j].y);
    if (mark>180) mark=360-mark;
    temp+=mark;
    return temp;
}

void DP()
{
    int i,j,temp;
    dp[0][1]=dis[0][1];
    for (j=2;j<=n;j++)
    {
        for (i=0;i<j-1;i++)
            dp[i][j]=dp[i][j-1]+dis[j][j-1];
        for (i=0;i<j-1;i++)
        {
            temp=dp[i][j-1]+dis[i][j];
            if (temp<dp[j-1][j])
                dp[j-1][j]=temp;
        }
    }
    dp[n][n]=dp[n-1][n]+dis[n-1][n];
}

int main()
{
    int i,j,t;
    scanf("%d",&t);
    while (t--)
    {
        scanf("%d",&n);
        for (i=1;i<=n;i++)
            scanf("%d%d",&a[i].x,&a[i].y);
        a[0].x=a[0].y=0;
        sort(a,a+n+1,cmp);
        for (i=0;i<=n;i++)
            for (j=0;j<=n;j++)
            dis[i][j]=cal(i,j);
        memset(dp,inf,sizeof(dp));
        DP();
        printf("%d\n",dp[n][n]+10*n);

    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-08 00:31:55

HDU 4824 双调旅行商问题的相关文章

hdu 4824 Disk Schedule(双调欧几里得旅行商问题)

题目链接:hdu 4824 Disk Schedule 题目大意:中文题. 解题思路:需要的时,很明显每到一层是要读取一次数据的,但是因为需要返回00,所以有些层的数据可以在返回的过程中读取会较优.于是转化成了双调欧几里得旅行商问题. #include <cstdio> #include <cstring> #include <cstdlib> #include <algorithm> using namespace std; const int N = 1

POJ 2677(双调旅行商问题&lt;bictonicTSP&gt;

Tour Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 3470 Accepted: 1545 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 must dete

【双调欧几里得】HDU 4824

通道:http://acm.hdu.edu.cn/showproblem.php?pid=4824 题意:中文题意 思路:裸双调欧几里得,关键在于转换思路就好了,把磁盘的每一层看作是已经X排序过的. 代码: TAG:双调欧几里得 以下是双调欧几里得学习资料. 欧几里得旅行商问题是对平面上给定的n个点确定一条连接各点的最短闭合旅程的问题.如图(a)给出了一个7个点问题的解.这个问题的一般形式是NP完全的,故其解需要多于多项式的时间. J.L. Bentley 建议通过只考虑双调旅程(bitonic

百度之星资格赛——Disk Schedule(双调旅行商问题)

Disk Schedule Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 2368    Accepted Submission(s): 333 Problem Description 有非常多从磁盘读取数据的需求,包含顺序读取.随机读取.为了提高效率,须要人为安排磁盘读取.然而.在现实中,这样的做法非常复杂. 我们考虑一个相对简单的

双调旅行商问题 (Bitonic TSP)

问题描写叙述: 上述问题能够使用动态规划的方法来解决. 以下是解决思路的详细介绍: 1. 最优子结构: 如果d[i][j]表示从起点1出发到达i及j两个顶点的最短路程之和. 为此能够如果K为此段路程上与j相加的节点.则d[i][j] = d[i][k] + len[k][j]. 证明:若存在一个更短的路径d[i][k],则就应该存在更短的路径d[i][j].这与如果矛盾,因此得证. 以下来寻找j相邻的节点,当中若i<j-1,则显然k=j-1,若i=j-1.则显然k属于(1,j-2)之间.为此得到

HDU2224&amp;POJ2677 双调旅行商问题

给出n个点,按X坐标升序给出,从1号点走到N号点再返回1号点所需的最小距离,要求所有点至少被走到一次 要求1->n的路上所经过的点X坐标升序 n->1路上所经过的点X坐标降序 具体详解参考:http://blog.csdn.net/xiajun07061225/article/details/8092247 #include "stdio.h" #include "string.h" #include "math.h" const d

图论 500题——主要为hdu/poj/zoj

转自——http://blog.csdn.net/qwe20060514/article/details/8112550 =============================以下是最小生成树+并查集======================================[HDU]1213   How Many Tables   基础并查集★1272   小希的迷宫   基础并查集★1325&&poj1308  Is It A Tree?   基础并查集★1856   More i

hdu图论题目分类

=============================以下是最小生成树+并查集====================================== [HDU] 1213 How Many Tables 基础并查集★ 1272 小希的迷宫 基础并查集★ 1325&&poj1308 Is It A Tree? 基础并查集★ 1856 More is better 基础并查集★ 1102 Constructing Roads 基础最小生成树★ 1232 畅通工程 基础并查集★ 123

CSU 1527 Bounty Hunter dp 双调旅行商

题目链接:点击打开链接 裸的双调旅行商问题啦 #include <stdio.h> #include <string.h> #include <iostream> #include <math.h> #include <queue> #include <set> #include <algorithm> #include <stdlib.h> using namespace std; #define ll in