Brief
As the title, put up a bit of a mixed backpack optimal time
Code area
#include<bits/stdc++.h> using namespace std; const int Max = 1e5+10; int n, v; int val[Max], vol[Max], num[Max]; int que[Max]; int dp[Max]; void work() { memset(dp, 0, sizeof(dp)); for (int i = 1; i <= n; i++) { if (num[i] == 1) //01背包 { for (intV = J; J> = [I] Vol; J, ) DP [J] = max (DP [J], DP [J - Vol [I]] + Val [I]); Continue ; } IF (Vol [I] * NUM [I]> = V) // complete backpack, the more critical, because very time-consuming process queue monotone { for ( int J = Vol [I]; J <= V; J ++ ) DP [J ] = max (DP [J], DP [J - Vol [I]] + Val [I]); Continue ; } for ( int RES = 0 ; RES <Vol [I]; RES ++) // enumerator I { int head = 0 , tail = - . 1 ; for ( int K = 0 ; K <= (V - RES) / Vol [I]; K ++) // Enumeration k ', i.e., a number of arithmetic progression, each updated with the number of the remainder // because only the same number of remainders will interact { int value DP = [K * Vol [I] + RES] - Val K * [I]; // current value IF (tail - head K ==) // even if all the materials can not be exhausted from the que [head] transfer head ++ ; the while (head <= tail && que [tail] <= value) // takes a maximum value tail--; tail++; que[tail] = value; dp[k * vol[i] + res] = que[head] + k * val[i]; } } } }