题目就是给你
n,m
a1,a2......an c1,c2.......cn
n种物品,第一种物品价值a1有c1个
问你能组合出多少种不超过m的价格
多重背包+二进制优化(脑补一下其实优化了好多时间啊)
其实不用分成完全背包和多重背包两部分也能过,我这个也是学别人的,之后试了一下不分开写的,也过了
#include <iostream> #include <cstring> #include <cstdio> using namespace std; bool dp[100005]; int val[105]; int num[105]; int main() { int n,m; int i,j,k; while (scanf("%d%d",&n,&m) && (n+m)) { for(i=1;i<=n;++i) scanf("%d",val+i); for(i=1;i<=n;++i) scanf("%d",num+i); memset(dp, false, sizeof(dp)); dp[0]=true; for(i=1;i<=n;++i) { if(val[i]*num[i]>=m) { for(j=val[i];j<=m;j++) { dp[j] = dp[j-val[i]]||dp[j]; } } else { for(j=1;j<=num[i];j<<=1) { for(k=m;k>=j*val[i];--k) { dp[k] = dp[k]||dp[k-val[i]*j]; } num[i]-=j; } if(num[i]>0) { for(k=m;k>=val[i]*num[i];--k) dp[k]=dp[k]||dp[k-val[i]*num[i]]; } } } int cnt = 0; for(i=1;i<=m;++i) if(dp[i]) cnt++; printf("%d ",cnt); } }