Openjudge 7624 山區建小學

2022-07-08 19:45:15 字數 1478 閱讀 1774

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

元培-from whf

動態規劃來解決,這裡需要乙個輔助的陣列dist,dist[i][j]表示在從i到j這一段區間建一所小學,i到j的村莊都到這個學校來上學的路程和。

狀態表達:f[i][j]表示前i個村莊建j所學校,到裡那個村莊最近的學校上學的路程和。

狀態轉移:f[i][j] = std::min(f[i][j],f[k][j-1]+dist[k+1][i]),也就是:

for(int i = 1;i<=n;i++)

for(int j = 1;j狀態數量:n^2

轉移代價:o(n)

時間複雜度:o(n^3)

空間複雜度:o(n^2)

還有乙個關鍵點,就是有關如何求dist陣列的,其實,我們可以發現,在i到j村莊裡建小學,選i到j村莊的路程的中間位置村莊,一定是最優的。畫個圖你就能發現了。

如何快速求dist呢,其實,dist[i][j]等於dist[i][j-1]+num[j]-num[i+j]/2的,建議畫個圖。

#include#include#include#include#includeint num[1001],dist[1001][1001],f[1001][1001];

int main()

for(int i = 1;i<=n;i++)

for(int j = i;j<=n;j++)

dist[i][j] = dist[i][j-1]+num[j]-num[(i+j)/2];

memset(f,0x3f,sizeof(f));

for(int i = 1;i<=n;i++)f[i][1] = dist[1][i];

for(int i = 1;i<=n;i++)

for(int j = 1;jfor(int k = 1;kf[i][j] = std::min(f[i][j],f[k][j-1]+dist[k+1][i]);

std::cout

}

openjudge7624 山區建小學

描述 在某山區修建了一條道路,恰好穿越總共m個村莊的每個村莊一次,沒有迴路或交叉,任意兩個村莊只能通過這條路來往。已知任意兩個相鄰的村莊之間的距離為di 為正整數 其中,0 i m。為了提高山區的文化素質,又決定從m個村中選擇n個村建小學 設 0 n m 500 請根據給定的m n以及所有相鄰村莊的...

openjudge 數字統計

總時間限制 1000ms 記憶體限制 100000kb 描述輸入n個整數,統計每個數出現的次數.輸入 第一行是乙個整數n 1 n 1000 接下來n行每行乙個整數.輸出 第一行輸出總共有多少個不同的整數.接下來每行輸出乙個整數及這個整數出現的次數,用空格分隔.輸出的整數的順序與它們在輸入中第一次出現...

Openjudge 括號匹配

這個用了普通的迴圈,資料量不是很大的話效率還是不錯的,如果資料比較大的話,換別的方法可能效率會高一點。思路很簡單 以字串中是否還存在沒有匹配過的 作為這個字串已經處理完畢的標誌。1,讀入字串,並進行處理,把所有不是 和 的字元都轉換成空格。2,從開始掃瞄字串,如果掃瞄到 記錄 的位置,直到掃瞄到 3...