原题传送门
用背包做,如果可以直接枚举物品以及核心数量
复杂度是
4000
∗
50
∗
2000
=
4
e
8
4000*50*2000=4e8
4000∗50∗2000=4e8差不多可以
那么我们基本上就知道怎么做了
想着怎么把
f
f
f的限制去掉
可以直接按照
f
f
f从大到小排序,那么我们就能保证现在手里面拥有的肯定都可以用来做任务
然后就做一个背包
Code:
#include <bits/stdc++.h>
#define maxn 2010
#define maxm 200010
#define LL long long
using namespace std;
const LL inf = 1e12;
struct data{
int c, v, f;
}a[maxn << 1];
LL dp[maxm];
int n, m;
inline int read(){
int s = 0, w = 1;
char c = getchar();
for (; !isdigit(c); c = getchar()) if (c == '-') w = -1;
for (; isdigit(c); c = getchar()) s = (s << 1) + (s << 3) + (c ^ 48);
return s * w;
}
bool cmpf(data x, data y){
return x.f == y.f ? x.v < y.v : x.f > y.f;
}
int main(){
freopen("cloud.in", "r", stdin);
// freopen("cloud.out", "w", stdout);
n = read();
for (int i = 1; i <= n; ++i){
a[i].c = read(), a[i].f = read(), a[i].v = -read();
}
m = read();
for (int i = 1; i <= m; ++i){
a[n + i].c = read(), a[n + i].f = read(), a[n + i].v = read();
}
sort(a + 1, a + 1 + m + n, cmpf);
dp[0] = 0;
for (int i = 1; i < maxm; ++i) dp[i] = -inf;
LL cnt = 0;
for (int i = 1; i <= n + m; ++i){
if (a[i].v < 0){
for (int j = cnt; j >= 0; --j)
dp[j + a[i].c] = max(dp[j + a[i].c], dp[j] + a[i].v);
cnt += a[i].c;
} else{
for (int j = 0; j <= cnt; ++j)
dp[j] = max(dp[j], dp[j + a[i].c] + a[i].v);
}
}
LL ans = 0;
for (int i = 0; i <= cnt; ++i) ans = max(ans, dp[i]);
printf("%lld\n", ans);
return 0;
}