1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61
| const int inf = 0xcf; const int maxn = 20000 + 10; int n, m;
int f[maxn]; int W[maxn], V[maxn], C[maxn];
void init() { Set(f, inf); f[0] = 0; }
inline int g(int i, int u, int k) { return f[u + k * V[i]] - k * W[i]; }
void solve() { init();
_rep(i, 1, n) { scanf("%d%d%d", &V[i], &W[i], &C[i]); _for(u, 0, V[i]) { deque<int> que;
// == status variable p == int maxp = (m - u) / V[i]; _forDown(k, maxp - 1, max(0, maxp - C[i])) { while (!que.empty() && g(i, u, que.back()) <= g(i, u, k)) que.pop_back(); que.push_back(k); }
_forDown(p, maxp, 0) { // == compare que.front and p-1 while (!que.empty() && que.front() > p - 1) que.pop_front(); if(!que.empty()) f[u + p * V[i]] = max(f[u + p * V[i]], g(i, u, que.front()) + p * W[i]);
// == compare que.back and maintain monotonic queue if(p - 1 - C[i] >= 0) { int k2 = p - 1 - C[i]; while (!que.empty() && g(i, u, que.back()) <= g(i, u, k2)) que.pop_back(); que.push_back(k2); } } // == status variable finished == } } int ans = 0; _rep(i, 1, m) ans = max(ans, f[i]); cout << ans << endl; }
int main() { freopen("input.txt", "r", stdin); int T; scanf("%d", &T);
while (T--) { scanf("%d%d", &m, &n); solve(); } }
|