题目描述
设有1g、2g、3g、5g、10g、20g的砝码各若干枚(其总重<=1000),
输入输出格式
输入格式:
输入方式:a1 a2 a3 a4 a5 a6
(表示1g砝码有a1个,2g砝码有a2个,…,20g砝码有a6个)
输出格式:
输出方式:Total=N
(N表示用这些砝码能称出的不同重量的个数,但不包括一个砝码也不用的情况)
输入输出样例
输入样例#1: 复制
1 1 0 0 0 0
输出样例#1: 复制
Total=3
分析:背包问题,多重背包。这里是把多重背包转化为01背包,用到了一种叫二进制拆分的方法,有兴趣可以去网上查下。
1 //It is made by HolseLee on 12th May 2018 2 //Luogu.org 2347 3 #include<bits/stdc++.h> 4 #define Fi(i,a,b) for(int i=a;i<=b;i++) 5 #define Fm(i,a,b) for(int i=a;i>=b;i--) 6 using namespace std; 7 const int N=4007; 8 int m[7]={0,1,2,3,5,10,20}; 9 int n[N],c[N],dp[N],tot,ans,k; 10 int main() 11 { 12 ios::sync_with_stdio(false); 13 Fi(i,1,6){cin>>n[i];tot+=n[i]*m[i];} 14 Fi(i,1,6){for(int j=1;j<=n[i];j*=2){ 15 c[++k]=m[i]*j;n[i]-=j;} 16 if(n[i])c[++k]=n[i]*m[i];} 17 Fi(i,1,k)Fm(j,tot,c[i]) 18 dp[j]=max(dp[j],dp[j-c[i]]+c[i]); 19 Fi(i,1,tot)if(dp[i]==i)ans++; 20 cout<<"Total="<<ans<<endl;return 0; 21 }