HDU 2191 mourns the victims of the 512 Wenchuan earthquake-Cherish the present and be grateful for your life (multiple backpacks)
Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 2191
Question:
Assume that you have funds of N yuan, and then there are m kinds of rice. The price for each type of rice is cost [I], the weight is Val [I], and the quantity is num [I]. now, how much rice can you buy with N yuan?
Analysis:
This is a typical problem of multiple backpacks.
We set DP [I] [J] = x to only buy the first I rice, and the total cost <= J indicates that the maximum weight of the rice purchased is X.
Initialization: DP is all 0.
Since each type of rice has a quantity of num [I], we can do this in the following two cases:
When cost [I] * num [I]> = N, we can directly perform a complete backpack process on the rice.
When cost [I] * num [I] <n, we regard num [I] as Class I rice as the following k + 1 item:
1 (Class I items) 2 4 2 ^ (k-1) and num [I]-2 ^ k + 1
We create a 01 backpack for each of the above k + 1 items to cover all the choices we may make for the I items.
Final Demand: DP [m] [N] value.
AC code:
# Include <cstdio> # include <cstring> # include <algorithm> using namespace STD; const int maxn = 4000 + 5; int N; // The amount of int m; // rice type int cost [100 + 5]; // price int Val [100 + 5]; // weight int num [100 + 5]; // Number of int DP [maxn]; // One Time 01 backpack void zero_one_pack (INT cost, int Val) {for (INT I = N; I >= cost; I --) DP [I] = max (DP [I], DP [I-cost] + val);} // void complete_pack (INT cost, int Val) {for (INT I = cost; I <= N; I ++) DP [I] = max (DP [I], DP [I-cost] + val );} // void multiple_pack (INT cost, int Val, int num) {If (Cost * num> = N) {complete_pack (cost, Val); return ;} int K = 1; while (k <num) {zero_one_pack (K * cost, K * val); num-= K; K * = 2;} zero_one_pack (Num * cost, num * val);} int main () {int t; scanf ("% d", & T); While (t --) {// read the input scanf ("% d", & N, & M); For (INT I = 1; I <= m; I ++) scanf ("% d", & cost [I], & Val [I], & num [I]); // initialization + recursive memset (DP, 0, sizeof (DP); For (INT I = 1; I <= m; I ++) multiple_pack (cost [I], Val [I], num [I]); // output result printf ("% d \ n", DP [N]);} return 0 ;}
HDU 2191 mourns the victims of the 512 Wenchuan earthquake-Cherish the present and be grateful for your life (multiple backpacks)