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