[蓝桥杯 2022 国 B] 搬砖
题目描述
这天,小明在搬砖。
他一共有 n n n 块砖,他发现第 i i i 砖的重量为 w i w_{i} wi,价值为 v i v_{i} vi。他突然想从这些砖中选一些出来从下到上堆成一座塔,并且对于塔中的每一块砖来说,它上面所有砖的重量和不能超过它自身的价值。
他想知道这样堆成的塔的总价值(即塔中所有砖块的价值和)最大是多少。
输入格式
输入共 n + 1 n+1 n+1 行, 第一行为一个正整数 n n n, 表示砖块的数量。
后面 n n n 行, 每行两个正整数 w i , v i w_{i}, v_{i} wi,vi 分别表示每块砖的重量和价值。
输出格式
一行,一个整数表示答案。
样例 #1
样例输入 #1
5
4 4
1 1
5 2
5 5
4 3
样例输出 #1
10
提示
【样例说明】
选择第 1 1 1、 2 2 2、 4 4 4 块砖,从上到下按照 2 2 2、 1 1 1、 4 4 4 的顺序堆成一座塔,总价值为 4 + 1 + 5 = 10 4+1+5=10 4+1+5=10。
【评测用例规模与约定】
对于 20 % 20 \% 20% 的数据,保证 n ≤ 10 n \leq 10 n≤10;
对于 100 % 100 \% 100% 的数据,保证 n ≤ 1000 ; w i ≤ 20 ; v i ≤ 20000 n \leq 1000 ; w_{i} \leq 20 ; v_{i} \leq 20000 n≤1000;wi≤20;vi≤20000 。
蓝桥杯 2022 国赛 B 组 J 题。
思路
这道题无非就两种状态,选和不选,这不就是01背包问题,只不过我们不知道背包的总容量,但我们可以按照如下公式进行推导:
第一次见dp还要堆其他的先进行排序。
其实:总的来说,题目要求的是:对于塔中的每一块砖来说,它上面所有砖的重量和不能超过它自身的价值。因此背包容量跟重量和价值有关,然后我们就看图里面说的。
最好可以参考。
代码
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N = 100010;
struct E{
int x,y;
}e[N];
int f[N];//这道题就是类似01背包问题,只不过多了些限制
//根据图中的我们可以
int n;
int main(){
cin>>n;
for(int i=1;i<=n;i++){
int a,b;
cin>>a>>b;
e[i]={a,b};
}
sort(e+1,e+1+n,[&](E a,E b){
return a.x+a.y<b.x+b.y;
});
//e[i].x+e[i].y是背包容量
int res=0;
for(int i=1;i<=n;i++){
for(int j=e[i].x+e[i].y;j>=e[i].x;j--){
f[j]=max(f[j],f[j-e[i].x]+e[i].y);
res=max(res,f[j]);
}
}
cout<<res;
return 0;
}