n,m
给出A1,A2,A3...AN;C1,C2,C3...CN;
给出硬币的价值和个数,问在1-M中间能构造出多少个组合
思路:
n种物品的价值,n种物品的个数;
一种物品能组成多种物品的0/1背包
#include<bits/stdc++.h> using namespace std; const int N=1e2+10; const int M=100000+10; int n,m; int val[N],num[N]; bool dp[M]; void Oneorzero(int v) { for(int i=m;i>=v;i--) if(dp[i-v]) dp[i]=true; } void Complete(int v) { for(int i=v;i<=m;i++) if(dp[i-v]) dp[i]=true; } int main() { while(~scanf("%d%d",&n,&m)) { if(!n&&!m) break; for(int i=1;i<=n;i++) scanf("%d",&val[i]); for(int i=1;i<=n;i++) scanf("%d",&num[i]); int k,v; dp[0]=true; for(int i=1;i<=m;i++) dp[i]=false; for(int i=1;i<=n;i++) { if(num[i]*val[i]>=m) Complete(val[i]); else { k=1; while(k<=num[i]) { v=val[i]*k; Oneorzero(v); num[i]-=k; k<<=1; } v=val[i]*num[i]; Oneorzero(v); } } int ans=0; for(int i=1;i<=m;i++) if(dp[i]) ans++; printf("%d ",ans); } return 0; }