题目描述
Frank
是一个非常喜爱整洁的人。他有一大堆书和一个书架,想要把书放在书架上。书架可以放下所有的书,所以Frank
首先将书按高度顺序排列在书架上。但是Frank
发现,由于很多书的宽度不同,所以书看起来还是非常不整齐。于是他决定从中拿掉k本书,使得书架可以看起来整齐一点。
书架的不整齐度是这样定义的:每两本书宽度的差的绝对值的和。例如有4本书:
1×21×2
5×35×3
2×42×4
3×13×1
那么Frank
将其排列整齐后是:
1×21×2
2×42×4
3×13×1
5×35×3
不整齐度就是2+3+2=72+3+2=7
已知每本书的高度都不一样,请你求出去掉k本书后的最小的不整齐度。
输入输出格式
输入格式:
第一行两个数字nn和kk,代表书有几本,从中去掉几本。(1≤n≤100,1≤k<n1≤n≤100,1≤k<n)
下面的nn行,每行两个数字表示一本书的高度和宽度,均小于200200。
保证高度不重复
输出格式:
一行一个整数,表示书架的最小不整齐度。
输入输出样例
输入样例#1:
4 1
1 2
2 4
3 1
5 3
输出样例#1:
3
思路:
我们先把书本从低到高排序,然后我们设dp[i][j]
代表前i本书去掉j本(一定包含第i本)的最小不整齐度。我们初始dp[0][0] = 0
,其余为无穷大,那么:
if(j + 1 == i)
dp[i][j] == 0;
else
dp[i][j] = min(dp[k][j - (book[i].h - book[k].h - 1)] + book[i].w - book[k].w) (1 <= k < i)
最后dp[k][j - (n - k)]
最小的即为答案
代码:
/*************************************************************************
> File Name: p.cpp
> Author: Zcy
> Mail: 296763002@qq.com
> Created Time: 三 1/23 18:16:17 2019
************************************************************************/
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <algorithm>
using namespace std;
int dp[105][105]; //前i本书去掉j本的最小不整齐度,i本必取
struct node {
int h, w;
}book[105];
bool cmp(node A, node B) {
return A.h < B.h;
}
int main () {
int n, k, minn = 0x3f3f3f3f;
scanf("%d%d", &n, &k);
for (int i = 1; i <= n; i++) {
scanf("%d%d", &book[i].h, &book[i].w);
}
sort(book + 1, book + n + 1, cmp);
memset(dp, 0x3f3f3f3f, sizeof(dp));
dp[0][0] = 0;
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= k && j < i; j++) {
if (i == j + 1) {
dp[i][j] = 0;
continue;
}
for (int p = 0; p < i; p++) {
if (j - (i - p - 1) >= 0) {
dp[i][j] = min(dp[p][j - (i - p - 1)] + abs(book[i].w - book[p].w), dp[i][j]);
}
}
}
}
for (int i = 1; i <= n; i++) {
if (k - (n - i) >= 0) {
minn = min(dp[i][k - (n - i)], minn);
}
}
printf("%d\n", minn);
return 0;
}
如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢