标签:
3 10
1 2 4 2 1 1
2 5
1 4 2 1
0 0
8
4
背包问题的复杂度是n*m,这题如果直接按照多重背包的计算会超时。所以和上一篇一样,多重背包的二分优化。
详细的说明在 http://www.cnblogs.com/agenthtb/p/5792628.html
代码如下:
1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 int w[100010],v[20010],maxn=0,dp[100010],n,m,cnt,x; 6 void f(int weight,int num)//把硬币进行二分的合并 7 { 8 for (int i=1;;i*=2) 9 { 10 if (num>=i) 11 w[cnt++]=weight*i; 12 else 13 { 14 w[cnt++]=num*weight; 15 return; 16 } 17 num-=i; 18 if (num<=0) 19 return; 20 } 21 } 22 int main() 23 { 24 //freopen("de.txt","r",stdin); 25 while (~scanf("%d%d",&n,&m)) 26 { 27 if (n==0&&m==0) 28 break; 29 memset(w,0,sizeof w); 30 memset(v,0,sizeof v); 31 memset(dp,0,sizeof dp); 32 dp[0]=1; 33 set<int>s; 34 cnt=1; 35 for (int i=1;i<=n;++i) 36 scanf("%d",&v[i]); 37 for (int i=1;i<=n;++i) 38 { 39 scanf("%d",&x); 40 f(v[i],x); 41 } 42 for (int i=1;i<cnt;++i) 43 { 44 for (int j=m;j>=w[i];--j) 45 { 46 if (dp[j-w[i]]) 47 dp[j]=1; 48 } 49 } 50 int ans=0; 51 for (int i=1;i<=m;++i) 52 if (dp[i]) ans++; 53 printf("%d\n",ans); 54 } 55 return 0; 56 }
标签:
原文地址:http://www.cnblogs.com/agenthtb/p/5838886.html