POJ 2392 Space Elevator ( 多重背包 背包限制不同 + 贪心 )

奶牛计划用不同类型的石头堆叠成空间电梯,每种石头有特定高度和数量限制,且总高度不可超过40。问题转化为多重背包问题,需考虑每个石头的独立高度限制。通过将石头按高度限制升序排列,并采用贪心策略,先放置高度小的石头,以最大化整体高度。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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
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.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
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 <cstdio>
#include <map>
#include <cstring>
#include <string>
#include <algorithm>
#include <cmath>
#include <set>
const int N = 100005;
using namespace std;
typedef long long ll;
struct node
{
    int c,h;
    int lim;
}a[405];
int dp[50005];
int m; //m为背包
bool cmp(node c,node d)
{
    return c.lim<d.lim;
}
void ZeroOnePack(int w,int v,int lim)
{
    for(int i=lim;i>=w;i--)           //不同的地方 限制不一样
        dp[i]=max(dp[i],dp[i-w]+v);
}
void  CompletePack(int w,int v,int lim)
{
    for(int i=w;i<=lim;i++)
        dp[i]=max(dp[i],dp[i-w]+v);
}
void  MultiplePack(int w,int v,int cnt,int lim)
{
    if(cnt*w>=lim) //物品无限的完全背包
    {
        CompletePack(w,v,lim);
        return ;
    }
    else{
    int k=1; //否则进行0-1背包转化
    while(k<=cnt){
        ZeroOnePack(k*w,k*v,lim);
        cnt-=k;
        k=k*2;
    }
    ZeroOnePack(cnt*w,cnt*v,lim);
    return ;
    }
}//完全背包模板
int main()
{
    int n;
    while(scanf("%d",&n)==1){
       int H=0;
        for(int i=1;i<=n;i++){
            scanf("%d%d%d",&a[i].h,&a[i].lim,&a[i].c);
            H=max(H,a[i].lim);
        }
    memset(dp,0,sizeof(dp));
    sort(a+1,a+n+1,cmp);
    for(int i=1;i<=n;i++)
        MultiplePack(a[i].h,a[i].h,a[i].c,a[i].lim);
    int ans=0;
    for(int i=1;i<=H;i++)
        ans=max(ans,dp[i]);
    printf("%d\n",ans);
    }
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值