openjudge7624 山區建小學

2022-07-27 05:45:13 字數 1496 閱讀 1185

描述

**在某山區修建了一條道路,恰好穿越總共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??,f[i][j]表示前i個村莊建立j所學校的最小距離,列舉前一所學校的管轄範圍,更新最小值即可。

1 #include2 #include3 #include4

using

namespace

std;

5int m,n,s[505],dis[505][505],f[505][505],d[505][505];6

int cal(int x,inty)7

14int

main()

1519

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

20for(int j=i+1 ; j<=m ; ++j)

21 dis[i][j]=dis[j][i]=s[j]-s[i];

22for(int i=1 ; i<=m ; ++i)

23for(int j=i+1 ; j<=m ; ++j)

24 d[i][j]=cal(i,j);

25for(int i=1 ; i<=m ; ++i)f[i][i]=0;26

for(int i=1 ; i<=m ; ++i )f[i][1]=d[1

][i];

27for(int i=2 ; i<=m ; ++i )

28for(int j=2 ; j<=min(i,n) ; ++j)

29for(int k=j-1 ; k<=i-1 ; ++k)

30 f[i][j]=min(f[i][j],f[k][j-1]+d[k+1

][i]);

31 printf("%d"

,f[m][n]);

32return0;

33 }

Openjudge 7624 山區建小學

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