题目链接:点击打开链接
题意:
牛要上太空;
要用砖造一座塔;
每块砖有高度 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;
}