日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

poj 1160(Post Office)

發(fā)布時(shí)間:2025/3/16 编程问答 22 豆豆
生活随笔 收集整理的這篇文章主要介紹了 poj 1160(Post Office) 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://poj.org/problem?id=1160


先講講我的思路:這道題首先很容易想到是用動(dòng)態(tài)規(guī)劃思想,所以我定義了一個(gè)二維數(shù)組dp[i][j],表示前j個(gè)位置,修建了i個(gè)郵局。所以推導(dǎo)出的狀態(tài)轉(zhuǎn)移方程為:

dp[i][j] = min{dp[i][j-1]+第j個(gè)位置到第i個(gè)郵箱位置的差,dp[i-1][k] + 第j個(gè)位置到第k+1個(gè)位置的差},實(shí)際上花括號(hào)里,左邊代表第i個(gè)郵箱不在第j個(gè)位置上,而右邊代表第i個(gè)

郵箱在第j個(gè)位置上,為了能夠確定dp[i][j]中第i個(gè)郵箱建立的位置,我用一個(gè)chosen[i][j]記錄下來(lái),表示前j個(gè)位置中,第i個(gè)郵箱建立的位置,這樣就可以直接計(jì)算第j個(gè)位置與

第i個(gè)郵箱位置的差。。此外,如果第i個(gè)郵箱有多個(gè)位置都滿足要求的話,那么盡可能地往右邊建。。

但是一直是WA。。。沒(méi)有想通到底是哪里出了問(wèn)題。。。


WA:

#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> using namespace std;const int maxn = 3300; const int inf = 0x3fff; int n,m,pos[maxn],dp[33][maxn],chosen[33][maxn];int main() { while(scanf("%d%d",&n,&m)!=EOF){memset(dp[0],0,sizeof(dp[0]));memset(chosen,0,sizeof(chosen));for(int i = 1; i <= n; i++)scanf("%d",&pos[i]);for(int j = 1; j <= n; j++)for(int k = j-1; k >= 1; k--)dp[0][j] += pos[j]-pos[k];for(int i = 1; i <= m; i++)for(int j = 1; j<= n; j++)dp[i][j] = inf;for(int i = 1; i <= m; i++) {dp[i][i] = 0;chosen[i][i] = i;}for(int j = 2; j <= n; j++){int sum = 0, choose = 0;dp[1][j] = dp[0][j];for(int k = j-1; k >= 1; k--){sum = 0;for(int t = k+1; t <= j; t++) sum += pos[t] - pos[k];if((dp[0][k]+sum < dp[1][j]) || ((dp[0][k]+sum == dp[1][j]) && (choose == 0))){dp[1][j] = dp[0][k] + sum;chosen[1][j] = k;choose = 1;}}}for(int i = 2; i <= m; i++)for(int j = i+1; j <= n; j++){if(dp[i][j-1] != inf){dp[i][j] = dp[i][j-1] + pos[j] - pos[chosen[i][j-1]];chosen[i][j] = chosen[i][j-1];}int sum = 0,choose = 0;for(int k = j-1; k >= i; k--){if(dp[i-1][k] != inf){if((dp[i-1][k] + sum < dp[i][j]) || ((dp[i-1][k] + sum == dp[i][j]) && (choose == 0))){dp[i][j] = dp[i-1][k] + sum;chosen[i][j] = j;choose = 1;}}sum += pos[j] - pos[k];}}printf("%d\n",dp[m][n]);}return 0; }

別人的思路:

1、考慮在V個(gè)村莊中只建立一個(gè)郵局的情況,顯然可以知道,將郵局建立在中間的那個(gè)村莊即可。也就是在a到b間建立

一個(gè)郵局,若使消耗最小,則應(yīng)該將郵局建立在(a+b)/2這個(gè)村莊上。

2、下面考慮建立多個(gè)郵局的問(wèn)題,可以這樣將該問(wèn)題拆分為若干子問(wèn)題,在前i個(gè)村莊中建立j個(gè)郵局的最短距離,是

在前k個(gè)村莊中建立j-1個(gè)郵局的最短距離與 在k+1到第i個(gè)郵局建立一個(gè)郵局的最短距離的和。而建立一個(gè)郵局我們?cè)?/span>

上面已經(jīng)求出。

3、狀態(tài)表示,由上面的討論,可以開(kāi)兩個(gè)數(shù)組

dp[i][j]:在前i個(gè)村莊中建立j個(gè)郵局的最小耗費(fèi)

sum[i][j]:在第i個(gè)村莊到第j個(gè)村莊中建立1個(gè)郵局的最小耗費(fèi)

那么就有轉(zhuǎn)移方程:dp[i][j] = min(dp[i][j],dp[k][j-1]+sum[k+1][i])? DP的邊界狀態(tài)即為dp[i][1] = sum[1][i];

所要求的結(jié)果即為dp[V][P];

4、然后就說(shuō)說(shuō)求sum數(shù)組的優(yōu)化問(wèn)題,可以假定有6個(gè)村莊,村莊的坐標(biāo)已知分別為p1,p2,p3,p4,p5,p6;那么,如果要

求sum[1][4]的話郵局需要建立在2或者3處,放在2處的消耗為p4-p2+p3-p2+p2-p1=p4-p2+p3-p1放在3處的結(jié)果為p4-

p3+p3-p2+p3-p1=p4+p3-p2-p1,可見(jiàn),將郵局建在2處或3處是一樣的。現(xiàn)在接著求sum[1][5],現(xiàn)在處于中點(diǎn)的村莊是

3,那么1-4到3的距離和剛才已經(jīng)求出了,即為sum[1][4],所以只需再加上5到3的距離即可。同樣,求sum[1][6]的時(shí)候

也可以用sum[1][5]加上6到中點(diǎn)的距離。所以有遞推關(guān)系:sum[i][j] = sum[i][j-1] + p[j] -p[(i+j)/2]

公式,還是公式的推理....

總結(jié)

以上是生活随笔為你收集整理的poj 1160(Post Office)的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。