- DP做法 : 转化为 01背包。 进行方案数 更新。最后统计种类。
-
#include<bits/stdc++.h> using namespace std; #define maxn 1234 int n,k,dp[maxn],len,sum,ans; int a[11]= {0,1,2,3,5,10,20}; vector<int>p; int main() { for(int i=1; i<=6; i++) { scanf("%d",&k); for(int j=0; j<k; j++) { p.push_back(a[i]); sum+=a[i]; } } dp[0]=1; len=p.size(); for(int i=0; i<len; i++) for(int j=sum; j>=p[i]; j--) dp[j]+=dp[j-p[i]]; for(int i=1; i<=sum; i++) if(dp[i])ans++; printf("Total=%d\n",ans); return 0; }
bitset 做法 :
因为 bitset 只能存 00 和 11 ,我们可以让第 ii 位为 11 来表示可以表示出 ii 这个值。
bitset能对某一位赋值,我们初始定义 Bitset[0]=1Bitset[0]=1,表示可以表示出 00
当我们加入一个新的砝码的时候,我们将这个砝码加入 bitset ,即进行如下的操作
Bitset |= Bitset << w[i]Bitset∣=Bitset<<w[i]
简单理解就是已有的所有能表示出的值都加上 w_iwi 再与原集合取并集。
最后我们统计 bitset 中有多少个 11 即可,可以使用自带函数 Bitset.count()Bitset.count() 完成。 -
#include<bits/stdc++.h> using namespace std; #define maxn 1234 int dp[maxn]; int a[11]= {0,1,2,3,5,10,20}; bitset<1010>s; int main() { for(int i=1; i<=6; i++)scanf("%d",&dp[i]); s[0]=1; for(int i=1; i<=6; i++) for(int j=0; j<dp[i]; j++) s|=s<<a[i]; printf("Total=%d\n",s.count()-1); return 0; }