poj2392 布尔值型 多重揹包

题目链接:点击打开链接


题意:

牛要上太空;

要用砖造一座塔;

每块砖有高度 h_i,数量 c_i,砖放下后的高度不超过 a_i;

求给你的砖能搭建的最高的高度是多少;


理解:

多重揹包,只是有些要注意的变化;

递推式含义:dp[i] 表示能否从前一个高度推导过来;

即:dp[i] = (dp[i - h_i] == 1);

其中用过的砖的数量要小于 c_i 个,并且砖放下后高度不超过 a_i;

还需注意的是 a_i 越小的砖应该先放,这是一个贪心的策略;


代码如下:


#include <cstdio>
#include <cstring>
#include <cmath>
#include <ctime>

#include <iostream>
#include <algorithm>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <queue>
#include <stack>

using namespace std;

typedef long long LL;
typedef pair<int, int> PII;

const int MIN_INF = 1e-7;
const int MAX_INF = (1e9) + 7;

#define X first
#define Y second

typedef pair<PII, int> PPI;

int dp[40010], sum[40010];

bool cmp(PPI p1, PPI p2) {
    return p1.Y < p2.Y;
}

int main() {
    int k, mx = -1;
    cin >> k;
    vector<PPI> vec(k);
    for (int i = 0; i < k; ++i) {
        cin >> vec[i].X.X >> vec[i].Y >> vec[i].X.Y;  // XX = h_i, XY = c_i, Y = a_i
        mx = max(mx, vec[i].Y);
    }
    sort(vec.begin(), vec.end(), cmp);

    dp[0] = 1;

    int ans = 0;
    for (int i = 0; i < k; ++i) {
        memset(sum, 0, sizeof(sum));
        for (int j = vec[i].X.X; j <= mx; ++j) {
            if (dp[j] == 0 && dp[j - vec[i].X.X] != 0 && j <= vec[i].Y && sum[j - vec[i].X.X] + 1 <= vec[i].X.Y) {
                sum[j] = sum[j - vec[i].X.X] + 1;
                dp[j] = 1;
                ans = max(ans, j);
            }
        }
    }

    cout << ans << endl;

    return 0;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章