Original title Link: click here
Problem Solving Ideas:
Multi-knapsack problem, not very understanding, understand the supplementary.
The idea of an online blog is:
for each coin: IF value x number >=m then the number of times to take this coin is equal to unlimited, can be considered as a complete backpack ELSE then consider 0-1 backpack (binary optimization), is to combine the V and num of this coin outof the possible state of the 0-1 backpack (which can be seen in the Backpack IX) (for NUM, which is similar to encoding.) when 2 2^n (n=0,1,2, ...) Indicates a state, which corresponds to a number of binary numbers is 1, and then there is a state is K>NUM/2 time, num+1-K, so down can use K to assemble all possible from the 1->num. Then for K, the unit value and size are multiplied by K and become a 0-1 backpack)
View Code
The source code is as follows:
#include <stdio.h>#include<algorithm>#include<string.h>using namespacestd; Const intmax=100000; intDp[max]; intC[max],w[max]; intv; voidZeroonepack (intCostintWei// on{ inti; for(i = v;i>=cost;i--) {Dp[i]= Max (dp[i],dp[i-cost]+Wei); } } voidCompletepack (intCostintWei//completely{ inti; for(i = cost;i<=v;i++) {Dp[i]= Max (dp[i],dp[i-cost]+Wei); } } voidMultiplepack (intCostintWeiintCnt//multiple{ if(v<=cnt*Cost ) {Completepack (Cost,wei); return ; } Else { intK =1; while(k<=CNT) {Zeroonepack (k*cost,k*Wei); CNT= cnt-K; K=2*K; } zeroonepack (CNT*cost,cnt*Wei); } } intMain () {intN; while(~SCANF ("%d%d", &n,&v), n+v) {inti; for(i =0; i<n;i++) scanf ("%d",&C[i]); for(i =0; i<n;i++) scanf ("%d",&W[i]); Memset (DP,0,sizeof(DP)); for(i =0; i<n;i++) {multiplepack (c[i],c[i],w[i]); } intsum =0; for(i =1; i<=v;i++) { if(dp[i]==i) {sum++; }} printf ("%d\n", sum); } return 0; }
View Code
HDU 2844 Coins Multiple backpack