1. #include <iostream>
    2. using namespace std;
    3. class PackSolver {
    4. static const int MAXN = 1000 + 5;
    5. struct Node {
    6. int pos, val;
    7. } q[MAXN];
    8. int dp[MAXN] = {};
    9. int N, V;
    10. void zeroOnePack(int v, int w) {
    11. for (int i = V; i >= v; i--)
    12. dp[i] = max(dp[i], dp[i - v] + w);
    13. }
    14. void completePack(int v, int w) {
    15. for (int i = v; i <= V; i++)
    16. dp[i] = max(dp[i], dp[i - v] + w);
    17. }
    18. // 多重背包 N*V
    19. void multiPack(int v, int w, int s) {
    20. for (int i = 0; i < v; i++) {
    21. int hh = 0, tt = 0, stop = (V-i)/v;
    22. for (int k = 0; k <= stop; k++) {
    23. int val = dp[k*v+i] - k * w;
    24. while (hh < tt && q[tt - 1].val <= val) tt--;
    25. if (hh < tt && k - q[hh].pos > s) hh++;
    26. q[tt].val = val, q[tt++].pos = k;
    27. dp[k*v+i] = q[hh].val + k*w;
    28. }
    29. }
    30. }
    31. // 多重背包 N*V*LogS
    32. void multiPack(int v, int w, int s, bool) {
    33. for (int i = 1; i <= s; s -= i, i *= 2) zeroOnePack(v * i, w * i);
    34. if (s) zeroOnePack(v * s, w * s);
    35. }
    36. public:
    37. void f() {
    38. cin >> N >> V;
    39. int v, w, s;
    40. while (N--) {
    41. cin >> v >> w >> s;
    42. if (s == -1) zeroOnePack(v, w);
    43. else if (s == 0) completePack(v, w);
    44. else multiPack(v, w, s);
    45. }
    46. cout << dp[V] << endl;
    47. }
    48. };
    49. int main() {
    50. PackSolver s;
    51. s.f();
    52. }