题目分析
好久没有写背包了,因此找了一个多重背包练一下,因为多重背包是01背包和完全背包的结合,手生,写了有一会!!!
就是给你一下砖块,每一个砖块一个高度,给出数量和这样砖块最多能放的高度。。
这道题因为每个点的限制不一样,所以需要从限制小的先进行dp,因为限制大的可以放在限制小的上面,但是限制小的无法再往大的上面堆,这样就算错了。。
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int maxn = 405;
struct Node{
int h, a, c;
bool operator < (const Node temp)const{
return a < temp.a;
}
}node[maxn];
int dp[maxn*100];
void zeropack(int v, int h){
for(int j = v; j >= h; j--)
dp[j] = max(dp[j], dp[j-h]+h);
}
void complepack(int h, int v){
for(int j = h; j <= v; j++)
dp[j] = max(dp[j], dp[j-h]+h);
}
void multipack(int n){
memset(dp, 0, sizeof(dp));
for(int i = 0; i < n; i++){
if(node[i].h*node[i].c >= node[i].a) complepack(node[i].h, node[i].a);
else{
for(int k = 1; k <= node[i].c; k <<= 1){
zeropack(node[i].a, k*node[i].h);
node[i].c -= k;
}
if(node[i].c) zeropack(node[i].a, node[i].c*node[i].h);
}
}
}
int main(){
int K;
while(scanf("%d", &K) != EOF){
int cnt = 0;
for(int i = 0; i < K; i++)
scanf("%d%d%d", &node[i].h, &node[i].a, &node[i].c), cnt = max(cnt, node[i].a);
sort(node, node+K);
multipack(K);
int ans = 0;
for(int i = 0; i <= cnt; i++) ans = max(ans, dp[i]);
printf("%d\n", ans);
}
return 0;
}