Codeforces 294B - Shaass and Bookshelf 讲解(必看)

蒟蒻来讲题,还望大家喜。若哪有问题,大家尽可提!

Hello, 大家好哇!本初中生蒟蒻今天来讲一下Codeforces 294B - Shaass and Bookshelf !

=================================================

原题

Shaass has n books. He wants to make a bookshelf for all his books. He wants the bookshelf’s dimensions to be as small as possible. The thickness of the i-th book is ti and its pages’ width is equal to wi. The thickness of each book is either 1 or 2. All books have the same page heights.

在这里插入图片描述

Shaass puts the books on the bookshelf in the following way. First he selects some of the books and put them vertically. Then he puts the rest of the books horizontally above the vertical books. The sum of the widths of the horizontal books must be no more than the total thickness of the vertical books. A sample arrangement of the books is depicted in the figure.
在这里插入图片描述

Help Shaass to find the minimum total thickness of the vertical books that we can achieve.

Input
The first line of the input contains an integer n, (1 ≤ n ≤ 100). Each of the next n lines contains two integers ti and wi denoting the thickness and width of the i-th book correspondingly, ( 1   ≤   t i   ≤   2 ,   1   ≤ w i   ≤ 100 1 \leq ti \leq 2, 1 \leq wi \leq100 1 ti 2, 1 wi100).

Output
On the only line of the output print the minimum total thickness of the vertical books that we can achieve.


思路

这道题就可以用动态规划了,这里我们采用闫氏分析法(如图1.1):
图(1.1)
这道题就是个01背包,要么书竖着摆,要么横着摆。厚度为重量,宽度为价值,就能如图推出以下方程式:

  • f i , j = m i n ( f i , j − t i , f i , j + w i ) f_{i, j} = min(f_{i, j - t_{i}}, f_{i, j} + w_{i}) fi,j=min(fi,jti,fi,j+wi)

最后,输出的时候要把厚度都枚举一遍,判断该厚度所对应的宽度是否小于等于该厚度,若可以: r e s = m i n ( r e s , f n , i ) res = min(res, f_{n, i}) res=min(res,fn,i)


代码

#include <iostream>
#include <cstring>

using namespace std;

const int N = 1e2 + 10, M = 2e2 + 10;

int n, sumt;
int t[N], w[N];
int f[N][M];

int main()
{
	cin >> n;
	
	for (int i = 1; i <= n; i ++)
		cin >> t[i] >> w[i], sumt += t[i];
	
	memset(f, 0x3f, sizeof f);
	f[0][0] = 0;
	for (int i = 1; i <= n; i ++)
		for (int j = sumt; j >= 0; j --)
			f[i][j] = min((j >= t[i]) ? f[i - 1][j - t[i]] : 0x3f3f3f3f, f[i - 1][j] + w[i]);
			
	int res = 0x3f3f3f3f;
	for (int j = 0; j <= sumt; j ++)
		if (j >= f[n][j])
			res = min(res, j);
			
	cout << res << endl;
	return 0;
}

视频讲解

Codeforces 294B - Shaass and Bookshelf 讲解(必看!!!)


今天就到这里了!

大家有什么问题尽管提,我都会尽力回答的!最后,祝大家新年快乐!

吾欲您伸手,点的小赞赞。吾欲您喜欢,点得小关注!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值