时间复杂度 O(n*m) 代码 #include <bits/stdc++.h> using namespace std; const int N = 2e4 + 10; int n, m; int f[N], g[N], q[N], tt, hh; //f、g 互为滚动数组 int main() { scanf("%d %d", &n, &m); int v, w, s; for (int i = 1; i <= n; i ++) { scanf("%d %d %d", &v, &w, &s); memcpy(g, f, sizeof f); for (int j = 0; j < v; j ++) { hh = 0, tt = -1; for (int k = j; k <= m; k += v) { if (tt >= hh && k - q[hh] > s * v) hh ++; //数量超过 s, 弹出 while (tt >= hh && g[q[tt]] - (q[tt] - j) / v * w <= g[k] - (k - j) / v * w) tt --; //维护窗口最大值 q[++ tt] = k; //压入当前值 f[k] = g[q[hh]] + (k - q[hh]) / v * w; //从窗口最大值进行转移 } } } printf("%d\n", f[m]); return 0; }