POJ 1742 Coins
多重背包二进制优化,o(10*100*100000)的复杂复,2800ms卡过去的。
#include<cstdio> #include<cstring> #include<cmath> #include<queue> #include<algorithm> using namespace std; struct X { int val; int num; }s[100+10]; int n,m; bool flag[100000+10]; int b[20]; int y[20]; void init() { b[0]=1; for(int i=1;i<=10;i++) b[i]=2*b[i-1]; } int main() { init(); while(~scanf("%d%d",&n,&m)) { if(n==0&&m==0) break; for(int i=1;i<=m;i++) flag[i]=0; flag[0]=1; for(int i=1;i<=n;i++) scanf("%d",&s[i].val); for(int i=1;i<=n;i++) scanf("%d",&s[i].num); for(int i=1;i<=n;i++) { int tmp=s[i].num; int k=0; while(1) { if(b[k]<tmp) { y[k]=b[k]; tmp=tmp-b[k]; } else { y[k]=tmp; break; } k++; } for(int h=0;h<=k;h++) { int V=s[i].val*y[h]; for(int j=m;j>=V;j--) if(flag[j-V]==1) flag[j]=1; } } int ans=0; for(int i=1;i<=m;i++) if(flag[i]==1) ans++; printf("%d\n",ans); } return 0; }