1. 程式人生 > >2014年百度之星程序設計大賽 - 資格賽 1002 Disk Schedule(雙調歐幾裏得旅行商問題)

2014年百度之星程序設計大賽 - 資格賽 1002 Disk Schedule(雙調歐幾裏得旅行商問題)

problem code 數據讀取 包括 想是 tracking sample cout http

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


解題思路:

這題目和雙調歐幾裏得旅行商問題思想是一樣的,從一個點出發,不反復的到達每個點,最後到達起點。求最短距離。

現學的這個,參考:

http://www.cppblog.com/doer-xee/archive/2009/11/30/102296.html

http://www.cnblogs.com/-sunshine/archive/2012/07/23/2605251.html

http://blog.csdn.net/xiajun07061225/article/details/8092247

代碼:

#include <iostream>
#include <algorithm>
#include <cmath>
using namespace std;
const int maxn=1010;
const int inf=0x7fffffff;
int cas;
int n;
struct Node
{
    int t,s;
}node[maxn];
double dp[maxn][maxn];

int dis(Node a,Node b)//計算兩個磁道讀取數據位置的距離(包含磁道距離+扇區距離)
{
    int ci=abs(a.t-b.t)*400;
    int MAX=(a.s>b.s?

a.s:b.s); int MIN=(a.s<b.s?a.s:b.s); int shan=min(MAX-MIN,360-MAX+MIN); return ci+shan; } int DP(int n)//雙調歐幾裏得旅行商問題算法 { dp[1][2]=dis(node[1],node[2]); for(int j=3;j<=n;j++) { for(int i=1;i<=j-2;i++) dp[i][j]=dp[i][j-1]+dis(node[j-1],node[j]); dp[j-1][j]=inf; for(int k=1;k<=j-2;k++) { int temp=dp[k][j-1]+dis(node[k],node[j]); if(temp<dp[j-1][j]) dp[j-1][j]=temp; } } dp[n][n]=dp[n-1][n]+dis(node[n-1],node[n]); return dp[n][n]; } int main() { cin>>cas; while(cas--) { cin>>n; node[1].t=0,node[1].s=0; for(int i=1;i<=n;i++) cin>>node[i+1].t>>node[i+1].s; n++; cout<<DP(n)+10*(n-1)<<endl;//別忘了加上讀取數據的時間 } return 0; }



2014年百度之星程序設計大賽 - 資格賽 1002 Disk Schedule(雙調歐幾裏得旅行商問題)