蒟蒻来讲题,还望大家喜。若哪有问题,大家尽可提!
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 ≤wi ≤100).
Output
On the only line of the output print the minimum total thickness of the vertical books that we can achieve.
思路
这道题就可以用动态规划了,这里我们采用闫氏分析法(如图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,j−ti,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 讲解(必看!!!)
今天就到这里了!
大家有什么问题尽管提,我都会尽力回答的!最后,祝大家新年快乐!
吾欲您伸手,点的小赞赞。吾欲您喜欢,点得小关注!