HDU 3591 the trouble of Xiaoqian (multiple backpacks + 01 backpacks)
Http://acm.hdu.edu.cn/showproblem.php? PID = 1, 3591
Question:
There is a currency system with n currencies. the nominal value of each currency is Val [I]. Now Xiaojie holds num [1], num [2],… Num [N]: 1st, 2nd... In the nth currency, buy a commodity with a value of T (t <= 20000). He gives the salesperson a currency with a total value of T> = T, and then the salesperson (possibly, if Jack gives the money> T, he must find the money. the salesperson always uses the least coin to find money for Xiaojie. now the question is: when Jack buys a product worth t, the number of coins he gives to the salesperson + the minimum number of coins that the salesman finds is equal?
Analysis:
We need at least X coins when we make dp1 [J] = x to represent the coins that Xiao Jie has paid to the salesclerk J. we need at least X coins when we make dp2 [J] = x to represent the coin that the salesperson gives Xiaojie value to J.
The previous problem was a multi-bag problem (because of the limited number of coins), and the 2nd problem was a full bag problem (the salesman had unlimited coins ).
In the end, we want to ask for: min (dp1 [T + I] + dp2 [I]) Where I belongs to [0, 20000-t].
For the first multi-backpack problem:
We set dp1 [I] [J] = x to indicate that at least X coins are required to make J money with the first I coins.
Initialization: dp1 is INF and dp1 [0] [0] = 0.
For the I-th coin, we need to handle the situation:
If Val [I] * num [I]> = 20000, perform a full backpack.
If Val [I] * num [I] <20000, you can view the new k + 1 item and then perform k + 1 backpack.
In the end, we want dp1 [N] [J], which is the dp1 [J] we mentioned earlier.
For the second complete backpack problem:
We set dp2 [I] [J] = x to indicate that at least X coins are required to make J money with the first I coins.
Initialization: dp2 is INF and dp2 [0] [0] = 0.
Status transfer: dp2 [I] [J] = min (dp2 [I-1] [J], dp2 [I] [J-Val [I] + 1) // sum is the sum.
The former indicates that none of the I currencies are used, and the latter indicates that the I currencies must use at least one.
The final question: dp2 [N] [J] The dimension array is the dp2 [J] we asked above.
Finally, let I traverse one side from t + 1 to 20000 to find the value of min (dp1 [T], dp1 [I] + dp2 [I-t.
AC code:
# Include <cstdio> # include <cstring> # include <algorithm> using namespace STD; # define INF 1e8const int maxn = 100 + 5; int N; // n currencies int t; // commodity amount int Val [maxn]; // each currency face value int num [maxn]; // number of each currency: int dp1 [20000 + 5]; int dp2 [20000 + 5]; // 01 void zero_one_pack (int * DP, int cost, int sum) {for (INT I = 20000; I >= cost; I --) DP [I] = min (DP [I], DP [I-cost] + sum); // note that + sum is used here, instead of + 1} // void complete_pack (int * DP, int cost) in the complete backpack Process) {for (in T I = cost; I <= 20000; I ++) DP [I] = min (DP [I], DP [I-cost] + 1 );} // void multiply_pack (int * DP, int cost, int sum) {If (Cost * sum> = 20000) {complete_pack (DP, cost ); return;} int K = 1; while (k <sum) {zero_one_pack (DP, cost * k, k); sum-= K; K * = 2 ;} zero_one_pack (DP, cost * sum, sum);} int main () {int Kase = 0; while (scanf ("% d", & N, & T) = 2) {// exit. Otherwise, WA if (n = 0 & t = 0) break; // read the input for (INT I = 1; I <= N; I ++) scanf ("% d", & Val [I]); For (INT I = 1; I <= N; I ++) scanf ("% d", & num [I]); // initialize for (INT I = 0; I <= 20000; I ++) dp1 [I] = dp2 [I] = inf; dp1 [0] = dp2 [0] = 0; // recursive for (INT I = 1; I <= N; I ++) multiply_pack (dp1, Val [I], num [I]); For (INT I = 1; I <= N; I ++) complete_pack (dp2, Val [I]); // output result int ans = dp1 [T]; for (INT I = t + 1; I <= 20000; I ++) ans = min (ANS, dp1 [I] + dp2 [I-t]); printf ("case % d: % d \ n", ++ Kase, ANS = inf? -1: ANS);} return 0 ;}
HDU 3591 the trouble of Xiaoqian (multiple backpacks + 01 backpacks)