山區建小學

2022-05-12 07:38:59 字數 1657 閱讀 9388

描述

**在某山區修建了一條道路,恰好穿越總共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 5

using

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以及所有相鄰村莊的...