dp P1103 書本整理 洛谷
阿新 • • 發佈:2019-03-11
main adg 兩個 一行 pre region def scan \n
題目描述
Frank
是一個非常喜愛整潔的人。他有一大堆書和一個書架,想要把書放在書架上。書架可以放下所有的書,所以Frank
首先將書按高度順序排列在書架上。但是Frank
發現,由於很多書的寬度不同,所以書看起來還是非常不整齊。於是他決定從中拿掉k本書,使得書架可以看起來整齊一點。
書架的不整齊度是這樣定義的:每兩本書寬度的差的絕對值的和。例如有4本書:
1×21 \times 21×2
5×35 \times 35×3
2×42 \times 42×4
3×13 \times 13×1
那麽Frank
將其排列整齊後是:
1×21 \times 21×2
2×42 \times 42×4
3×13 \times 13×1
5×35 \times 35×3
不整齊度就是2+3+2=72+3+2=72+3+2=7
已知每本書的高度都不一樣,請你求出去掉k本書後的最小的不整齊度。
輸入輸出格式
輸入格式:
第一行兩個數字nnn和kkk,代表書有幾本,從中去掉幾本。(1≤n≤100,1≤k<n1 \le n \le 100, 1 \le k<n1≤n≤100,1≤k<n)
下面的nnn行,每行兩個數字表示一本書的高度和寬度,均小於200200200。
保證高度不重復
輸出格式:
一行一個整數,表示書架的最小不整齊度。
輸入輸出樣例
輸入樣例#1: 復制4 1 1 2 2 4 3 1 5 3輸出樣例#1: 復制
3
這個是一個dp,這個應該可以不是特別難的判斷出來,但是這個定義不是很好去定義,我又沒有想出來,最後看題解定義的
dp數組定義為前i本書選了j本書,且i為最後結束的那本書,然後之後的轉移就比較好轉移,就往下一本書要不要,
要的話是接在那個之後最好,所以這裏有三重循環,我雖然意識到了,但是呢,沒有寫出來,最後還是借助題解寫完的,這個要註意的就是有些前i個選不出j個,因為可能i<j。註意一下這裏就好了。
#include <stdio.h> #include <string.h> #include <algorithm> #include <iostream> #define inf 0x3f3f3f3f using namespace std; const int maxn = 110; int dp[maxn][maxn];//表示從前面i本書中選j本,且以第i本為結束的最小整齊度。 struct node { int h, d; }exa[maxn]; bool cmp(node a, node b) { return a.h < b.h; } int main() { int n, k; cin >> n >> k; for (int i = 1; i <= n; i++) { scanf("%d%d", &exa[i].h, &exa[i].d); } sort(exa + 1,exa + 1 + n, cmp); for (int i = 0; i <= n; i++) { dp[i][1] = 0; } for (int i = 1; i <= n; i++) { for (int j = 2; j <= min(n-k,i); j++) { dp[i][j] = inf; for (int k = j-1; k <=i-1 ; k++) { dp[i][j] = min(dp[k][j - 1] + abs(exa[i].d - exa[k].d), dp[i][j]); } } } int ans = inf; for (int i = n-k; i <= n; i++) ans = min(dp[i][n - k], ans); printf("%d\n", ans); return 0; }
dp P1103 書本整理 洛谷