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

百度之星资格赛——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

有非常多从磁盘读取数据的需求,包含顺序读取、随机读取。为了提高效率,须要人为安排磁盘读取。然而。在现实中,这样的做法非常复杂。

我们考虑一个相对简单的场景。磁盘有很多轨道,每一个轨道有很多扇区,用于存储数据。当我们想在特定扇区来读取数据时,磁头须要跳转到特定的轨道、详细扇区进行读取操作。为了简单,我们如果磁头能够在某个轨道顺时针或逆时针匀速旋转,旋转一周的时间是360个单位时间。磁头也能够任意移动到某个轨道进行读取,每跳转到一个相邻轨道的时间为400个单位时间,跳转前后磁头所在扇区位置不变。一次读取数据的时间为10个单位时间。读取前后磁头所在的扇区位置不变。

磁头同一时候仅仅能做一件事:跳转轨道,旋转或读取。如今,须要在磁盘读取一组数据,如果每一个轨道至多有一个读取请求,这个读取的扇区是轨道上分布在 0到359内的一个整数点扇区,即轨道的某个360等分点。

磁头的起始点在0轨道0扇区。此时没有数据读取。

在完毕全部读取后,磁头须要回到0轨道0扇区的始点位置。请问完毕给定的读取所需的最小时间。

 


Input

输入的第一行包括一个整数M(0<M<=100),表示測试数据的组数。

对于每组測试数据,第一行包括一个整数N(0<N<=1000),表示要读取的数据的数量。之后每行包括两个整数T和S(0<T<=1000,0<= S<360)。表示每一个数据的磁道和扇区,磁道是按升序排列,而且没有反复。

 


Output

对于每组測试数据。输出一个整数。表示完毕所有读取所需的时间。

 


Sample Input

3
1 10 
3
1 20 
3 30
5 10
1 10
2 11

 

 


Sample Output

830 4090 1642

 

题解:參照欧几里德旅行商问题仅仅需把本题中的两个点的距离用(距离=两点的轨道差*400+两点的扇区差)取代就可以; 
须要注意的是扇区差是轨道小弧的长度:即(360+a[j].y-a[i].y)%360与abs(a[i].y-a[j].y)的较小者。如扇区350与扇区10的距离是20而不是340。
另一点就是要把起点(0,0)加上。
以下是转自大神们的欧几里德旅行商问题的思路;链接http://blog.csdn.net/weyuli/article/details/19752217
事实上所谓的欧几里德旅行商问题就是
从1到n 然后在从n到1的最短路 ,去的时候经过的点的顺序必须从小到大, 来的时候经过的点的顺序必须从大到小, 而且每一个点仅仅能经过一次(1和n不算), 输出最短路的长度。

思路【转】:
  欧几里得旅行商问题是对平面上给定的n个点确定一条连接各点的最短闭合旅程的问题。如图(a)给出了一个7个点问题的解。

这个问题的一般形式是NP全然的,故其解须要多于多项式的时间。

J.L. Bentley 建议通过仅仅考虑双调旅程(bitonic tour)来简化问题,这样的旅程即为从最左点開始。严格地从左到右直至最右点,然后严格地从右到左直至出发点。

下图(b)显示了相同的7个点的最短双调路线。

在这样的情况下,多项式的算法是可能的。其实。存在确定的最优双调路线的O(n*n)时间的算法。

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

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

注:在一个单位栅格上显示的平面上的七个点。 a)最短闭合路线,长度大约是24.89。这个路线不是双调的。b)同样点的集合上的最短双调闭合路线。长度大约是25.58。

这是一个算导上的思考题15-1。

首先将给出的点排序,keywordx。又一次编号。从左至右1,2。3,…。n。

定义d[i][j],表示结点i到结点j之间的距离。

定义dp[i][j]。表示从i连到1,再从1连到j。(注意,i>j。且并没有相连。)

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

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

对于随意一个点i来说。有两种连接方法,一种是如图(a)所看到的,i与i-1相连,还有一种呢是如图(b)。i与i-1不相连。

依据双调旅程。我们知道结点n一定与n相连,那么,假设我们求的dp[n][n-1],仅仅需将其加上d[n-1][n]就是最短双调闭合路线。

依据上图。非常easy写出方程式:

dp[i][j]=dp[i-1][j]+d[i][i-1];

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

以下是代码实现:


#include <cstdio>#include <cstring>#include <cmath>using namespace std;const int maxn = 1010;int dp[maxn][maxn];int d[maxn][maxn];struct point{    int x, y;}a[maxn];int dis(int i, int j)                   //计算两点之间的距离{     int p,q;     if(a[i].y>a[j].y)          q=(360+a[j].y-a[i].y)%360;     else          q=(360+a[i].y-a[j].y)%360;          p=abs(a[i].y-a[j].y)>q?

q:abs(a[i].y-a[j].y); //求出小弧的长度 return (abs(a[i].x-a[j].x)*400+p); //距离=两点的轨道差*400+两点的扇区差}int main(){ int t,n; scanf("%d",&t); while(t-- ) { scanf("%d", &n); a[1].x=0; a[1].y=0; //把起点(0,0)加上 for(int i = 2; i <= n+1; i++) scanf("%d %d", &a[i].x, &a[i].y); for(int i = 1; i <= n+1; i++) { for(int j = 1; j <= n+1; j++) { d[i][j] = dis(i, j); //d[i][j]为i点到j点的距离 } } dp[1][2] = d[1][2]; for(int i = 3; i <= n+1; i++) { for(int j = 1; j < i-1; j++) { dp[j][i] = dp[j][i-1] + d[i-1][i]; /* dp[j][i]为j点到1点,再从1点到i点的距离,这一步是为下一循环求dp[i][i+1]做准备。事实上就是图a */ } dp[i-1][i] = 999999999; for(int j = 1; j < i-1; j++) { int sum = dp[j][i-1] + d[j][i]; if(dp[i-1][i] > sum) dp[i-1][i] = sum; /* dp[i-1][i]为i-1点到1点,再从1点到i点的最短距离,这个距离仅仅要加上边d[i-1][i]就是从1点到i点的最短闭合旅程,事实上就是图b */ } } dp[n+1][n+1] = dp[n][n+1] + d[n][n+1]; printf("%d\n", dp[n+1][n+1]+10*n); /* dp[n+1][n+1]就是终于的最短闭合旅程,n+1点到1点。再从1点到n+1点的最短距离 ,10*n为读取点中数据的时间 */ } return 0;}

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/115511.html原文链接:https://javaforall.net

(0)
上一篇 2022年2月3日 下午12:00
下一篇 2022年2月3日 下午1:00


相关推荐

  • StringBuilder使用方法

    StringBuilder使用方法图 4 2StringBuild 类 StringBuilde 类位于命名空间 System Text 中 在使用它时 可以在文件头通过 using 语句引入该空间 usingSystem Text 声明 StringBuilde 对象需要使用 new 关键字 并可以对其进行初始化 如下语句声明了一个 StringBuilde 对象 myStringBuil 并初始化为 Hello S

    2026年3月26日
    2
  • eclipse中文档注释快捷键_eclipse文档注释

    eclipse中文档注释快捷键_eclipse文档注释Eclipse中的两种注释方法:(1)多行注释(2)单行注释一、多行注释快捷键1:添加注释Ctrl+Shift+/:  添加/**/注释 示例:选中代码块后按下快捷键即可/*floatsize=0.0f;  floatpct=0.0f;  try{size=Float.parseFloat(resInf

    2022年8月15日
    8
  • 数据库之——sqlite下载及使用

    数据库之——sqlite下载及使用最近在研究 sqlite 的数据库 是因为项目需要存储大量数据 也需要查询 比起 txt 或者 excel xml 等方式 综合还是想用数据库保存 但是公司项目没有实施工程师 使用 sqlserver 怕客户不会安装 所以希望可以安装项目软件的时候自动安装 sql 数据库 查了很久的资料 还没有很好的方式解决 偶然发现 sqlite 不需要安装 很方便能部署到打包文件里面 如果你和我有同样的问题 可以使用 sqlite 的数

    2026年3月17日
    1
  • vim不能复制粘贴_在筛选状态下怎么复制粘贴

    vim不能复制粘贴_在筛选状态下怎么复制粘贴前言这是一则记录贴,防止小技巧遗忘。不知道大家是否会有这种困扰,例如在AndroidStudio有一段缩进优美的代码实现,例如:publicvoidsayHello(){Stringmsg=”HelloVimPasteMode”;System.out.println(msg);}当你把这段缩进优美的代码直接ctrl+c,ctrl+v到Vim的时候,就会出现如

    2025年11月22日
    5
  • js子页面获取父页面元素_iframe跨域调用父页面方法

    js子页面获取父页面元素_iframe跨域调用父页面方法@{List<Customer>Custs=newList<Customer>();Custs.Add(newCustomer{CustomerCode=”1001″,CustomerName=”Shiv”});Custs.Add(newCustomer{Custome…

    2026年4月17日
    4
  • vue 获取当前路由的子路由

    vue 获取当前路由的子路由获取当前路由的子路由 routes varroutes children this router options routes varroute this route matched for vari 0 i route length 1 i routes routes children find e e name route length 1 i routes routes children find e

    2026年3月16日
    3

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号