描述
**在某山區修建了一條道路,恰好穿越總共m個村莊的每個村莊一次,沒有迴路或交叉,任意兩個村莊只能通過這條路來往。已知任意兩個相鄰的村莊之間的距離為di(為正整數),其中,0 < i < m。為了提高山區的文化素質,**又決定從m個村中選擇n個村建小學(設 0 < n < = m < 500 )。請根據給定的m、n以及所有相鄰村莊的距離,選擇在哪些村莊建小學,才使得所有村到最近小學的距離總和最小,計算最小值。
輸入第1行為m和n,其間用空格間隔
第2行為(m-1) 個整數,依次表示從一端到另一端的相鄰村莊的距離,整數之間以空格間隔。
例如10 3
2 4 6 5 2 4 3 1 3
表示在10個村莊建3所學校。第1個村莊與第2個村莊距離為2,第2個村莊與第3個村莊距離為4,第3個村莊與第4個村莊距離為6,...,第9個村莊到第10個村莊的距離為3。輸出各村莊到最近學校的距離之和的最小值。樣例輸入
10 2樣例輸出3 1 3 1 1 1 1 1 3
18因為不可能出現二號到四號上學,三號到一號上學的情況,即乙個學校就會形成乙個區間(沒有重疊),於是我們用dp[m][n]表示在1至m的村莊中建立n所小學的最短路程。
對於每乙個dp[x][y]都有幾種情況:1,在村莊x建立第y所小學,此時dp[x][y]=dp[x-1][y-1]。2,在村莊x-i(x-i>=1)至村莊x的地方建立第y所小學(意思是:讓村莊x-i(x-i>=1)至村莊x都到y上學),
此時出現乙個問題,究竟應該建立在(x-i)至x的哪個位置,很容易想到列舉,但有更優的方法:在村莊1-5中建一所小學,應該建在(1+5)/2的位置上,可以自己去推理,我懶不寫推理過程了。
於是dp[x][y]=dp[x-i-1][y-1]+在(x+x-i+1)/2建小學的路程(可以不加乙隻是我算路程要求我必須加),還有乙個優化,比如我們算出了在x-i到x中建一所小學的路程數,
那麼x-i-1到x中建一所小學的路程數就等於x-i到x的路程數+x-i-1到本次小學的距離。
預處理時將dp[n][m]值為無限大,但dp[1][1--m]=0,dp[2--n][1]用前面說過的一種方法推出來。
其次用字首和更好算距離。
1 #include 2 #include 3 #include 4 #include 5using
namespace
std;67
int cnt_cun=0,cnt_scl=0;8
int jv[505]=;
9int dp[505][505]=;
10void
dpdt( );
1112
13void
dpdt( )
2324
25for(int x=2;x<=cnt_cun;x++)
28int fewr=dp[x-1][y-1],next_sze=x,next_jv=0;29
for(int z=x-1;z>=1;z--)
36 dp[x][y]=fewr;
37}
38}
39return
; 40}41
4243
intmain()
4950
dpdt( );
51 cout<5253
5455
56 }
luogu P4677 山區建小學
傳送門 聽說這題lyh只用了2分鐘就a了,ttql 發現只有乙個學校那麼就是找中位數,多個學校呢?我不知道在 建小學啊,mmp,dp列舉小學範圍的分界點。我是這麼理解的 所以f i j 表示i j建乙個學校的最小花費,就找中位數對吧。然後dp i j 表示前i個村建j個學校的最小花費,轉移方程 dp...
Openjudge 7624 山區建小學
在某山區修建了一條道路,恰好穿越總共m個村莊的每個村莊一次,沒有迴路或交叉,任意兩個村莊只能通過這條路來往。已知任意兩個相鄰的村莊之間的距離為di 為正整數 其中,0 i m。為了提高山區的文化素質,又決定從m個村中選擇n個村建小學 設 0 n m 500 請根據給定的m n以及所有相鄰村莊的距離,...
openjudge7624 山區建小學
描述 在某山區修建了一條道路,恰好穿越總共m個村莊的每個村莊一次,沒有迴路或交叉,任意兩個村莊只能通過這條路來往。已知任意兩個相鄰的村莊之間的距離為di 為正整數 其中,0 i m。為了提高山區的文化素質,又決定從m個村中選擇n個村建小學 設 0 n m 500 請根據給定的m n以及所有相鄰村莊的...