POJ 2392 Space Elevator 排序+多重背包

题目链接

题目大意,给你一些块,每个块的高度为Hi,能堆到最大高度为Ai,能使用的次数为Ci。问你最大能堆多大的高度。

很明显多重背包,但是不用计数什么的,就用dp[i]表示能不能到达i
然后递推的时候更新最大值。

但是有一个点需要考虑,一个是需要排序,就是先选Ai小的物品,这样才可能堆的高。

下面贴代码

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
using namespace std;

struct po
{
    int h,a,c;
};
bool cmp(po a,po b)
{
    return a.a<=b.a;
}

po mm[410];
int sum[410000];
int dp[400010];

int main()
{
    int n;
    scanf("%d",&n);
    for(int i=0;i<n;i++) scanf("%d%d%d",&mm[i].h,&mm[i].a,&mm[i].c);
    sort(mm,mm+n,cmp);

    memset(dp,0,sizeof(dp));
    dp[0] = 1;//初始化

    int ans = 0;
    for(int i=0;i<n;i++){

        memset(sum,0,sizeof(sum));//计数用了多少个

        for(int j=mm[i].h;j<=mm[i].a;j++){
            if(!dp[j] && dp[j-mm[i].h] && sum[j-mm[i].h] < mm[i].c){
                dp[j] = 1;
                ans = max(ans,j);
                sum[j] = sum[j-mm[i].h] + 1;
            }
        }

    }
    printf("%d\n",ans);
    return 0;

}

dp动态规划还是得多敲,这个东西,经验很重要,对于我这个渣渣来说。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值