显然对于每个城堡,派人越晚越好,我们令每个城堡只会在进行到最晚的能派人到这个城堡的时候考虑是否派人,对于派人,攻占完每一个城堡后考虑派人,显然先考虑重要性最大的。
那么我们就可以进行 dp 了,设 d p [ i ] [ j ] dp[i][j] dp[i][j] 表示攻占完第 i i i 个城堡后,有 j j j 个人的答案。
枚举当前城堡打完后会派出去几个人进行转移。
#include <bits/stdc++.h>
#define mp(x, y) make_pair(x, y)
#define pb emplace_back
#define FOR(x, l, r) for(int x = l, _##x = int(r); x <= _##x; x++)
#define DO(x, r, l) for(int x = r, _##x = int(l); x >= _##x; x--)
#define vi vector
#define ALL(x) x.begin(), x.end()
#define AL(x) x.begin() + 1, x.end()
#define X first
#define Y second
using namespace std;
const int MOD = 1e9 + 7;
const double eps = 1e-11;
template<class T>
using vi2 = vector<vector<T>>;
using ll = long long;
using pii = pair<int, int>;
int main() {
ios::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
auto solve = [&] () {
int n, m, k, tk = 0;
cin >> n >> m >> k;
tk = k;
vi<int> a(n + 1), b(n + 1), c(n + 1), mto(n + 1);
vi2<int> go(n + 1); // 当前城堡能派人到的城堡重要值
FOR(i, 1, n) cin >> a[i] >> b[i] >> c[i], tk += b[i];
FOR(i, 1, n) mto[i] = i;
FOR(i, 1, m) {
int u, v;
cin >> u >> v;
mto[v] = max(mto[v], u); // 找到最大的能向当前城堡派人的城堡编号
}
FOR(i, 1, n) {
go[mto[i]].pb(c[i]);
}
FOR(i, 1, n) sort(ALL(go[i]));
FOR(i, 1, n) {
go[i].pb(0);
reverse(ALL(go[i]));
FOR(j, 1, go[i].size() - 1) go[i][j] = go[i][j - 1] + go[i][j];
// 从大到小排序,求前缀和。
}
vi2<int> dp(n + 1, vi<int>(tk + 1, -1));
dp[0][k] = 0;
FOR(i, 0, n - 1) {
FOR(j, 0, tk) {
if(dp[i][j] == -1 || j < a[i + 1]) continue;
FOR(t, 0, go[i + 1].size() - 1) dp[i + 1][j + b[i + 1] - t] = max(dp[i + 1][j + b[i + 1] - t], dp[i][j] + go[i + 1][t]);
}
}
int ans = -1;
FOR(j, 0, tk) ans = max(ans, dp[n][j]);
cout << ans << endl;
};
int t = 1;
// cin >> t;
// scanf("%d", &t);
while(t--) solve();
return 0;
}