多重背包变形--poj2392

Language:
Space Elevator
Time Limit: 1000MS Memory Limit: 65536K
Total Submissions: 7307 Accepted: 3429

Description

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
每个物体有自己的高度限制,只需要把上限改为自己的限制即可,要先计算限制小的,也就是要对a进行排序

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
struct A
{
    int h,a,c;
} cow[405];
int dp[400005];
int max1,max2;
bool com(A c,A b)
{
    return c.a<b.a;
}
void zero(int hi,int ai)
{
    for(int i=ai; i>=hi; i--)
        dp[i]=max(dp[i],dp[i-hi]+hi);
}
void complete(int hi,int ai)
{
    for(int i=hi; i<=ai; i++)
        dp[i]=max(dp[i],dp[i-hi]+hi);
}
void mult(int cost,int hi,int ai,int ci)
{
    if(hi*ci>=ai)
        complete(hi,ai);
    else
    {
        int k=1;
        while(k<ci)
        {
            zero(k*hi,ai);
            ci-=k;
            k*=2;
        }
        zero(ci*hi,ai);
    }
}
int main()
{
    //freopen("in.txt","r",stdin);
    int k;
    while(cin>>k)
    {
        //max2=-1;
        for(int i=1; i<=k; i++)
        {
            cin>>cow[i].h>>cow[i].a>>cow[i].c;
        }
        sort(cow+1,cow+k+1,com);
        max1=-1;
        memset(dp,0,sizeof(dp));
        for(int i=1; i<=k; i++)
            mult(cow[i].h,cow[i].h,cow[i].a,cow[i].c);
        for(int i=0; i<=cow[k].a; i++)
            if(dp[i]>max1)
                max1=dp[i];
        cout<<max1<<endl;
    }
    return 0;
}



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值