標籤:code contest 請求 out 三個點 can service 檔案 www
Description「飛奔」快遞公司成立之後,已經分別與市內許多中小企業公司簽訂郵件收送服務契約。由於有些公司是在同一棟大樓內,所以「飛奔」公司收件的地點(收件點)最多隻有m點 (1, 2, …, m),因此「飛奔」僅先行採購了三輛貨車並聘用了三名司機,每天早上分別從收件地點 「1」, 「2」 及 「3」出發。而在與客戶的服務契約中有明確訂約:「飛奔」必須在客戶提出郵件寄送要求的隔天派人至該公司(地點)收件。 為了能更有效率的服務客戶並節省收件時間,該公司設立了收件服務登記網站,客戶如有郵件需要寄送,必須在需要收件的前一天就先上網登記。為了節省油量,「飛奔」就利用晚上先行安排三位司機隔天的收件路線。每位司機至各地點收件的順序應與各公司上網登記的順序相符且必須能在最省油的情況下完成當天所有的收件服務。因此每位司機有可能需要在不同時間重複到同一地點收件,或不同的司機有可能需在不同的時間點前往同一地點收件。 如下面範例二(收件公司地點依序為: 4 2 4 1 5 4 3 2 1)所示,雖然司機1一開始就已經在收件地點「1」了,但是他卻不能先把後面第四個登記的公司(地點「1」)郵件先收了再前往第一、第二、或第三個登記收件地點(地點「4」,「2」,「4」)收件。但是如果前三個登記收件的服務是由司機2或3來負責,則司機1就可以在地點「1」收了第四個登記的郵件後再前往後面所登記的地點收件。此外,在某些情況下,不一定每輛車都要收到貨,也就是說,最佳收件方式也有可能是只需出動一或兩輛車去收貨。請寫一個程式來幫「飛奔」公司計算每天依預約順序至各收件地點收件的最少總耗油量。Input輸入檔案第一行有一個整數 m(3 < = m < = 200),代表「飛奔」公司收件的地點數,以1至m之間的整數代號來表示每個地點。 接下來的m行(第2到第m+1行),每行有m個整數,代表一個矩陣D。第 i +1行的第 j 個整數是D(i, j),D(i, j) 代表司機開車從收件點 i 到收件點 j 所需耗油量。最後有一行數串,數串之數字依序為前一天上網登記要求收件的公司地點代號,最多會有1000個收件請求。輸入檔案中任兩個相鄰的整數都以一個空白隔開。 //D(i,j)<=maxint 注意:油量矩陣D滿足三角不等式,也就是說 D(i, j) < = D(i, k) + D(k, j),1 < = i, j, k < = m。因此,每輛車前往下一個收件地點時一定是直接前往,不必先繞道至其它地點再抵達下個收件地點。Output輸出一個整數,代表收件所需最少總耗油量。Sample Input4
0 5 0 6
6 0 5 6
1 6 0 6
1 1 1 0
1 1 1 1 4 4 2 2 2 3
Sample Output6
範例說明:到每個請求收件地點的司機分別為1 1 1 1 3 3 2 2 2 1,因此司機1隻需從起使點1移動到地點3,司機2隻需停留在地點2,司機3從起始點3移動到地點4。
HINTSource
JSOI2010第二輪Contest1
Solution
設計狀態,令f[w][i][j][k]為處理完第w個請求後,三輛車分別在i\j\k三個點的最小耗油量
因為一定有一輛車正好停在點a[w],所以省掉一維空間,得到f[w][i][j]
因為這樣做數組太大會逾時(有一定聯絡),考慮每一次都由上一個請求轉移到下一個請求,把w最佳化成滾動維
最後轉移一下就行了
#include <stdio.h>#include <memory.h>#define MaxN 1001#define MaxM 201#define dmin(a,b) ((a)<(b)?(a):(b))int g[MaxM][MaxM],a[MaxN],m,n,f[2][MaxM][MaxM],T,ans=0x3f3f3f3f;int main(){ scanf("%d",&n); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) scanf("%d",&g[i][j]); while(scanf("%d",&a[++m])!=EOF); memset(f,0x3f,sizeof f); f[T][1][2]=f[T][2][1]=g[3][a[1]]; f[T][2][3]=f[T][3][2]=g[1][a[1]]; f[T][1][3]=f[T][3][1]=g[2][a[1]]; for(int k=2;k<m;k++){ T^=1; memset(f[T],0x3f,sizeof f[T]); for(int i=1;i<=n;i++) for(int j=1;j<=n;j++){ f[T][i][j]=f[T][j][i]=dmin(f[T][i][j],f[T^1][i][j]+g[a[k-1]][a[k]]); f[T][a[k-1]][j]=f[T][j][a[k-1]]=dmin(f[T][a[k-1]][j],f[T^1][i][j]+g[i][a[k]]); f[T][a[k-1]][i]=f[T][i][a[k-1]]=dmin(f[T][a[k-1]][i],f[T^1][i][j]+g[j][a[k]]); } } for(int i=1;i<=n;i++)for(int j=1;j<=n;j++)ans=dmin(ans,f[T][i][j]); printf("%d\n",ans); return 0;}
[bzoj1820][JSOI2010][Express Service 快遞服務] (動態規劃)