1. 程式人生 > >dp P1103 書本整理 洛谷

dp P1103 書本整理 洛谷

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<n1n100,1k<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 書本整理 洛谷