洛谷P1103书本整理

题目描述

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: [email protected]
	> 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;
}

转载请注明出处!!!

如果有写的不对或者不全面的地方 可通过主页的联系方式进行指正,谢谢

猜你喜欢

转载自blog.csdn.net/Ivan_zcy/article/details/87905971