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;
}


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