For multiple knapsack problems, n items are used. Each item has a value v [I], and the quantity of each item is limited to num [I].
This question is how much value can be combined within the m range with all coins.
For each coin:
IF Value × quantity> = m
The number of times THEN took the coin is equivalent to no limit. You can consider it as a full backpack.
ELSE
THEN is considered as a 0-1 backpack (Binary optimization). It is to combine the v and num of the coin into the possible status of the 0-1 backpack (you can check the backpack for nine lectures)
(For num, it is similar to encoding. When 2 ^ n <= num/2: k = 2 ^ n (n = 0, 1, 2 ,......) Indicates the state, which is 1 for a single binary digit, and k> num/2 for another State. num + 1-k, in this way, k can be used to combine all the possibilities from 1-> num. Then for k, the unit value and size are multiplied by k and then become a 0-1 backpack)
AC code
[Cpp]
# Include <cstdio>
# Include <cstdlib>
# Include <cstring>
Const int maxv = 100001;
Const int maxn = 101;
Int v [maxn], num [maxn];
Int knap [maxv];
Int n, m;
Void multipleSack (int v, int num)
{
Int I, j, k;
Int space;
If (v * num> = m)
{
// Use a full backpack
For (space = v; space <= m; space ++)
{
Knap [space] = knap [space] | knap [space-v];
}
}
// Use the 01 backpack for Binary Optimization
For (k = 1; k <= num/2; k = (k <1 ))
{
For (space = m; space> = k * v; space --)
{
Knap [space] = knap [space] | knap [space-k * v];
}
}
K = num + 1-k;
For (space = m; space> = k * v; space --)
{
Knap [space] = knap [space] | knap [space-k * v];
}
Return;
}
Int main ()
{
Int I, j, k, t;
While (~ Scanf ("% d", & n, & m), n & m)
{
For (I = 1; I <= n; I ++)
{
Scanf ("% d", & v [I]);
}
For (I = 1; I <= n; I ++)
{
Scanf ("% d", & num [I]);
}
Memset (knap, 0, sizeof (knap ));
Knap [0] = 1;
For (I = 1; I <= n; I ++)
{
MultipleSack (v [I], num [I]);
}
For (I = 1, t = 0; I <= m; I ++)
{
T + = knap [I];
}
Printf ("% d \ n", t );
}
Return 0;
}
# Include <cstdio>
# Include <cstdlib>
# Include <cstring>
Const int maxv = 100001;
Const int maxn = 101;
Int v [maxn], num [maxn];
Int knap [maxv];
Int n, m;
Void multipleSack (int v, int num)
{
Int I, j, k;
Int space;
If (v * num> = m)
{
// Use a full backpack
For (space = v; space <= m; space ++)
{
Knap [space] = knap [space] | knap [space-v];
}
}
// Use the 01 backpack for Binary Optimization
For (k = 1; k <= num/2; k = (k <1 ))
{
For (space = m; space> = k * v; space --)
{
Knap [space] = knap [space] | knap [space-k * v];
}
}
K = num + 1-k;
For (space = m; space> = k * v; space --)
{
Knap [space] = knap [space] | knap [space-k * v];
}
Return;
}
Int main ()
{
Int I, j, k, t;
While (~ Scanf ("% d", & n, & m), n & m)
{
For (I = 1; I <= n; I ++)
{
Scanf ("% d", & v [I]);
}
For (I = 1; I <= n; I ++)
{
Scanf ("% d", & num [I]);
}
Memset (knap, 0, sizeof (knap ));
Knap [0] = 1;
For (I = 1; I <= n; I ++)
{
MultipleSack (v [I], num [I]);
}
For (I = 1, t = 0; I <= m; I ++)
{
T + = knap [I];
}
Printf ("% d \ n", t );
}
Return 0;
}
This can't be done on POJ, and another piece of code that can be done on POJ.
[Cpp]
# Include <iostream>
# Include <cstdio>
# Include <cstring>
Using namespace std;
Bool can_pay [100005];
Int use_ai [100005];
Int Ai [105], Ci [105];
Int n, m, ans;
Int coins ()
{
Int I, j;
Ans = 0;
For (I = 0; I <n; ++ I)
{
Memset (use_ai, 0, sizeof (use_ai ));
For (j = Ai [I]; j <= m; ++ j)
{
If (! Can_pay [j] & can_pay [j-Ai [I] & use_ai [j-Ai [I] <Ci [I])
{
Can_pay [j] = true;
Use_ai [j] = use_ai [j-Ai [I] + 1;
++ Ans;
}
}
}
Printf ("% d \ n", ans );
Return 0;
}
Int main ()
{
Int I;
While (scanf ("% d", & n, & m), n | m)
{
Memset (can_pay, false, sizeof (can_pay ));
Can_pay [0] = true;
For (I = 0; I <n; ++ I)
Scanf ("% d", & Ai [I]);
For (I = 0; I <n; ++ I)
Scanf ("% d", & Ci [I]);
Coins ();
}
Return 0;
}
# Include <iostream>
# Include <cstdio>
# Include <cstring>
Using namespace std;
Bool can_pay [100005];
Int use_ai [100005];
Int Ai [105], Ci [105];
Int n, m, ans;
Int coins ()
{
Int I, j;
Ans = 0;
For (I = 0; I <n; ++ I)
{
Memset (use_ai, 0, sizeof (use_ai ));
For (j = Ai [I]; j <= m; ++ j)
{
If (! Can_pay [j] & can_pay [j-Ai [I] & use_ai [j-Ai [I] <Ci [I])
{
Can_pay [j] = true;
Use_ai [j] = use_ai [j-Ai [I] + 1;
++ Ans;
}
}
}
Printf ("% d \ n", ans );
Return 0;
}
Int main ()
{
Int I;
While (scanf ("% d", & n, & m), n | m)
{
Memset (can_pay, false, sizeof (can_pay ));
Can_pay [0] = true;
For (I = 0; I <n; ++ I)
Scanf ("% d", & Ai [I]);
For (I = 0; I <n; ++ I)
Scanf ("% d", & Ci [I]);
Coins ();
}
Return 0;
}