The cows are going to space! They plan to achieve orbit by building a sort of space elevator: a giant tower of blocks. They have K (1 <= K <= 400) different types of blocks with which to build the tower. Each block of type i has height h_i (1 <= h_i <= 100) and is available in quantity c_i (1 <= c_i <= 10). Due to possible damage caused by cosmic rays, no part of a block of type i can exceed a maximum altitude a_i (1 <= a_i <= 40000).
Help the cows build the tallest space elevator possible by stacking blocks on top of each other according to the rules.
Input
-
Line 1: A single integer, K
-
Lines 2…K+1: Each line contains three space-separated integers: h_i, a_i, and c_i. Line i+1 describes block type i.
Output -
Line 1: A single integer H, the maximum height of a tower that can be built
Sample Input
3
7 40 3
5 23 8
2 52 6
Sample Output
48
Hint
OUTPUT DETAILS:
From the bottom: 3 blocks of type 2, below 3 of type 1, below 6 of type 3. Stacking 4 blocks of type 2 and 3 of type 1 is not legal, since the top of the last type 1 block would exceed height 40.
思路:给定总高度,各个模块的数量和高度和这些模块不能超过多高。多重背包问题,不过要先将各个模块的限高进行排序
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<string>
#include<string.h>
int dp[40005];
int Max;
struct Edge
{
int h, c, a;
const bool operator<(const Edge&rhs)const {
return a < rhs.a;
}
}edge[405];
using namespace std;
void ZeroOnePack(int w, int v,int m) {
int j;
for (j = m; j >= w; j--) {
dp[j] = max(dp[j], dp[j - w] + v);
Max=max(dp[j],Max);
}
}
void CompletePack(int w, int v,int m) {
int j;
for (j = w; j <= m; j++) {
dp[j] = max(dp[j], dp[j - w] + v);
Max=max(dp[j],Max);
}
}
void MultiplePack(int w, int v, int amount,int m) {
if (amount*w >= m) {
CompletePack(w, v,m);
return;
}
for (int k = 1; k < amount; k <<= 1) {
ZeroOnePack(k*w, k*v,m);
amount -= k;
}
ZeroOnePack(amount*w, amount*v,m);
}
int main() {
int k;
while (scanf("%d", &k) != EOF) {
memset(dp,0,sizeof(dp));
memset(edge,0,sizeof(edge));
Max=0;
for (int i = 1; i <= k; i++) {
scanf("%d %d %d", &edge[i].h, &edge[i].a, &edge[i].c);
}
sort(edge+1, edge + k+1);
for (int i = 1; i <= k; i++) {
MultiplePack(edge[i].h, edge[i].h, edge[i].c, edge[i].a);
}
printf("%d\n",Max);
}
return 0;
}