題意:牛們想造一個儘可能高的塔。他們有N種方塊,每種方塊高h_i,有c_i個,但是這種方塊只能在高度小於a_i時使用。問這個塔最高可以搭起到多高的高度。
思路:沒有高度限制的話,其實把所有的方塊都用上,纔是最高的高度。但是有了高度a_i限制後,就變成了容量限制的多重揹包。
可以注意到,方塊還要考慮擺放的順序問題,不同的擺放順序也會讓塔的高度不一樣。這樣,我們就想能否按照高度a_i從小到大進行排序。即a_i越小的先放。
這是中貪心的想法,可以證明這樣做不會失去最優解。
剩下的就是個多重揹包了。
代碼如下:
#include <cstdio>
#include <algorithm>
#include <cstring>
using namespace std;
const int MAX = 200010;
struct node{
int h,a,c;
node(){}
bool operator < (const node & rhs) const{
return a < rhs.a;
}
} ev[500];
int dp[MAX];
int main(void)
{
//freopen("input.txt","r",stdin);
int K;
scanf("%d",&K);
for(int i = 0; i < K; ++i)
scanf("%d%d%d",&ev[i].h,&ev[i].a,&ev[i].c);
sort(ev,ev+K);
dp[0] = 1;
int ans = 0;
for(int i = 0; i < K; ++i){
int num = ev[i].c;
for(int k = 1; num; k <<= 1){
int mul = min(k,num);
for(int j = ev[i].a ; j >= mul * ev[i].h; --j)
if(dp[j- ev[i].h*mul]) dp[j] = 1,ans = max(j,ans);
num -= mul;
}
}
printf("%d\n",ans);
return 0;
}