hdu2844Coins(多重揹包模板)
阿新 • • 發佈:2018-12-21
Coins
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 20860 Accepted Submission(s): 8198
You are to write a program which reads n,m,A1,A2,A3...An and C1,C2,C3...Cn corresponding to the number of Tony's coins of value A1,A2,A3...An then calculate how many prices(form 1 to m) Tony can pay use these coins.
Output For each test case output the answer on a single line.
Sample Output 8 4
多重揹包的模板題
1 #include <iostream> 2 #include <map> 3 #include <math.h> 4 #include <algorithm> 5 #include <vector> 6View Code#include <cstdlib> 7 #include <cstdio> 8 #include <cstring> 9 #include <set> 10 using namespace std; 11 int n,m,a[105],c[105],dp[100005]; 12 void comdp(int w,int v) 13 { 14 int i; 15 for(i=w; i<=m; i++) 16 dp[i]=max(dp[i],dp[i-w]+v); 17 } 18 void zeroone(int w,int v) 19 { 20 int i; 21 for(i=m; i>=w; i--) 22 dp[i]=max(dp[i],dp[i-w]+v); 23 } 24 void multidp(int w,int v,int cnt)//此時開始多重揹包,dp[i]表示揹包中重量為i時所包含的最大價值 25 { 26 if(cnt*w>=m)//此時相當於物品數量無限進行完全揹包 27 { 28 comdp(w,v); 29 return; 30 } 31 int k=1;//否則進行01揹包轉化,具體由程式碼下數學定理可得 32 while(k<=cnt) 33 { 34 zeroone(k*w,k*v); 35 cnt-=k; 36 k*=2; 37 } 38 zeroone(cnt*w,cnt*v); 39 return ; 40 } 41 int main() 42 { 43 while(~scanf("%d %d",&n,&m)) 44 { 45 if(n==0&&m==0)break; 46 for(int i=1;i<=n;i++)scanf("%d",&a[i]); 47 for(int i=1;i<=n;i++)scanf("%d",&c[i]); 48 memset(dp,0,sizeof(dp)); 49 int ans=0; 50 for(int i=1;i<=n;i++) 51 { 52 multidp(a[i],a[i],c[i]); 53 } 54 for(int i=1;i<=m;i++) 55 { 56 if(dp[i]==i)ans++; 57 } 58 printf("%d\n",ans); 59 } 60 return 0; 61 }