洛谷 P6771 [USACO05MAR] Space Elevator 太空电梯 题解

题目链接

洛谷 P6771 [USACO05MAR] Space Elevator 太空电梯

思路分析

由题意这是一道多重背包的题目。但是题目中还多了一个限制条件:第 \(i\) 种方块任何部分不能高于 \(a_i\)

首先考虑这样一个问题。还是题目中这三个条件,给定你一堆方块,你要怎么排列使它们最有可能满足条件?显而易见的,你应该把限制高度 \(a_i\) 小的放在下面,大的放在上面,才能尽量满足。

所以对于这道题,我们要先考虑 \(a_i\) 小的,再考虑 \(a_i\) 大的,只需在可行性的多重背包前先将物品排个序即可。另外由于方块不能高于 \(a_i\),枚举高度时只需从 \(a_i\) 开始枚举即可。时间复杂度 \(O(\sum{(a_i\cdot c_i)})\)

代码呈现

#include<bits/stdc++.h>
using namespace std;
struct node{
    int h,a,c;
};

const int N=405,M=4e4+10;
int n;
node a[N];
bool dp[M];

inline bool cmp(node a,node b){ return a.a<b.a; }
int main(){
    scanf("%d",&n);
    for (int i=1;i<=n;++i) scanf("%d%d%d",&a[i].h,&a[i].a,&a[i].c);
    sort(a+1,a+n+1,cmp);
    dp[0]=1; // 注意初始化
    for (int i=1;i<=n;++i){
        for (int j=1;j<=a[i].c;++j){
            for (int k=a[i].a;k>=a[i].h;--k) dp[k]|=dp[k-a[i].h];
        }
    }
    for (int i=a[n].a;i>=0;--i){ // 枚举答案
        if (dp[i]){ printf("%d",i);break; }
    }
    return 0;
}
posted @ 2026-01-11 13:27  CodingJuRuo  阅读(6)  评论(0)    收藏  举报