Title Link: HDOJ-1171
Main topic
There are n kinds of items, each of which has a size and quantity. Require that all items be divided into two parts so that the total size of the two parts is as close as possible.
Problem analysis
Make sum the sum of the sizes of all items. So it is the size of the smaller part to make a complete backpack with a given item and a backpack capacity of (SUM/2).
The complete knapsack problem can be optimized using a monotonic queue, O (nm).
Code
#include <iostream> #include <cstdio> #include <cstdlib> #include <cstring> #include <cmath > #include <algorithm>using namespace std;const int maxn = 5, MAXM = 250000 + 5;int N, Sum, Sum1, A, B, Hea D1, Tail1, Head2, Tail2;int V[MAXN], NUM[MAXN], Q1[MAXM], Q2[MAXM], F[maxm];int main () {while (true) {scanf ("%d", &n); if (n < 0) break; Sum = 0;for (int i = 1; I <= n; ++i) {scanf ("%d%d", &v[i], &num[i]); Sum + = v[i] * num[i];} SUM1 = Sum >> 1;for (int i = 0; I <= Sum1; ++i) f[i] = 0;int Ni, Vi, t;for (int i = 1; I <= n; ++i) {Ni = num[ I]; Vi = v[i];for (int j = 0; j < Vi; ++j) {Head1 = Tail1 = 0; Head2 = TAIL2 = 0;for (int k = j, Cnt = 0; k <= Sum1; k + = Vi, ++cnt) {if (Tail1-head1 = Ni + 1) {if (q2[head2 + 1] = = Q1[head1 + 1]) ++head2;++head1;} t = f[k]-Cnt * VI; Q1[++TAIL1] = T;while (Head2 < TAIL2 && Q2[tail2] < T)--tail2; Q2[++TAIL2] = T;f[k] = q2[head2 + 1] + Cnt * VI;}}} B = F[sum1]; A = Sum-b;printF ("%d%d\n", A, B);} return 0;}
[Hdoj 1171] Big Event in HDU "full backpack"