POJ Space Elevator(排序+多重揹包)
阿新 • • 發佈:2019-02-01
題目分析
好久沒有寫揹包了,因此找了一個多重揹包練一下,因為多重揹包是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;
}