标签:des style class blog code java
Disk Schedule Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 240 Accepted Submission(s): 121 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 1 10 3 1 20 3 30 5 10 2 1 10 2 11 Sample Output 830 4090 1642
第一次学双调欧几里得。。
双调欧几里得详解网上都有,在这就不贴出来了,只谈谈我对双调欧几里得的理解。
对于一个平面里的n个点,找出一条回路经过每个点一次,且路径最短。
把n个点分别标为1-n,dis(i,j)即为点i与点j直接相连的路径长度,dp[i][j](i>j)为连接前i个点的一条路径,且不是封闭的,i与j之间没有连线,就相当于一条线以i为首,以j为尾把前i个点串起来。
那么有dp[i][i-1]=min(dp[i-1][k]+dis(k,i)) //k<i-1,若想在前i-1个点相连的线上再串上点i且以i-1这个点为尾,那么就找出所有前i-1个点相连的线且以i-1为首k为尾+点k与 点i之间距离 最小的线即为dp[i][i-1]
dp[i][k]=dp[i-1][k]+dis(i,i-1) //k<i-1,若想把i串到线上,且这条线以i和k为两段,那么找出以i-1和k为两端的线,把i串到i-1那一头即可。
上述过程中的路径都是断开的即不是环。
那么如何求环呢,把n个点相连的线两头接起来就行了,即dp[n][k]+dis(n,k)。
对于本题,跳转轨道时只能挨个跳轨道,那么跳轨道的时间即为从0轨道一格一格跳到最大轨道处,然后再一格一格跳回来,这个好算。
然后是读取数据时间即为数据个数*10。
难点就是跳0-359范围的扇区时间,由于上述知识易知,最短的时间也就是把分布在0-359范围扇区只走一遍且是回路。
运用上述知识就可以写代码了,代码就不解释了:
1 #include <stdio.h> 2 #include <string.h> 3 #include <string> 4 #include <algorithm> 5 #define inf 999999999 6 using namespace std; 7 8 long long int dp[1005][1005]; 9 int n; 10 int a[1005]; 11 12 int dis(int i,int j) 13 { 14 int x1=a[i], x2=a[j]; 15 if(x1<x2) 16 swap(x1,x2); 17 return min(x1-x2,360-(x1-x2)); 18 } 19 20 long long int DP() 21 { 22 int i, j; 23 long long ans=0; 24 dp[0][1]=dp[1][0]=dis(0,1); 25 for(i=2;i<=n;i++) 26 { 27 dp[i][i-1]=inf; 28 for(j=0;j<i-1;j++) 29 { 30 dp[i][i-1]=min(dp[i][i-1],dp[i-1][j]+dis(i,j)); 31 dp[i][j]=dp[i-1][j]+dis(i,i-1); 32 } 33 } 34 ans=inf; 35 for(i=0;i<n;i++) 36 ans=min(ans,dp[n][i]+dis(n,i)); 37 return ans; 38 } 39 40 main() 41 { 42 int t, i, j; 43 int m; 44 scanf("%d",&t); 45 while(t--) 46 { 47 scanf("%d",&n); 48 for(i=1;i<=n;i++) 49 scanf("%d %d",&m,&a[i]); 50 printf("%I64d\n",DP()+n*10+m*800); 51 } 52 }
标签:des style class blog code java
原文地址:http://www.cnblogs.com/qq1012662902/p/3801603.html