Good Bye 2014 F
对于一种特殊的不可逆的dp的拆分方法。。
也可以用分治写哒。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PII pair<int, int> #define y1 skldjfskldjg #define y2 skldfjsklejg using namespace std; const int N = 4000 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; int n, p, c[N], h[N], t[N], L[10001][N], dp[N], a[20001], b[20001], ans[20001]; vector<int> v[20001]; vector<int> qus[20001]; void solve(int T) { int down = max(T - p + 1, 1), up = min(20000, T + p - 1); memset(dp, 0, sizeof(dp)); for(int k = T - 1; k >= down; k--) { for(int id : v[k]) { for(int j = N - 1; j >= c[id]; j--) dp[j] = max(dp[j - c[id]] + h[id], dp[j]); } memcpy(L[k - down], dp, sizeof(dp)); } memset(dp, 0, sizeof(dp)); for(int k = T; k <= up; k++) { for(int id : v[k]) { for(int j = N - 1; j >= c[id]; j--) dp[j] = max(dp[j - c[id]] + h[id], dp[j]); } for(int x : qus[k]) { for(int j = 0; j <= b[x]; j++) ans[x] = max(ans[x], dp[j] + L[k - T][b[x] - j]); } } } int main() { scanf("%d%d", &n, &p); for(int i = 1; i <= n; i++) { scanf("%d%d%d", &c[i], &h[i], &t[i]); v[t[i]].push_back(i); } int q; scanf("%d", &q); for(int i = 1; i <= q; i++) { scanf("%d%d", &a[i], &b[i]); qus[a[i]].push_back(i); } for(int i = 1; i <= 20000; i += p) { solve(i); } for(int i = 1; i <= q; i++) printf("%d ", ans[i]); return 0; } /* */