题目
某君有 <math> <semantics> <mrow> <mi> n </mi> </mrow> <annotation encoding="application/x-tex"> n </annotation> </semantics> </math>n 个互不相同的正整数,现在他要从这 <math> <semantics> <mrow> <mi> n </mi> </mrow> <annotation encoding="application/x-tex"> n </annotation> </semantics> </math>n 个正整数之中无重复地选取任意个数,并仅通过加法凑出整数 <math> <semantics> <mrow> <mi> X </mi> </mrow> <annotation encoding="application/x-tex"> X </annotation> </semantics> </math>X。
求某君有多少种不同的方案来凑出整数 <math> <semantics> <mrow> <mi> X </mi> </mrow> <annotation encoding="application/x-tex"> X </annotation> </semantics> </math>X。
输入格式
第一行,输入两个整数 <math> <semantics> <mrow> <mi> n </mi> <mo separator="true"> , </mo> <mi> X </mi> <mo> ( </mo> <mn> 1 </mn> <mo> ≤ </mo> <mi> n </mi> <mo> ≤ </mo> <mn> 20 </mn> <mo separator="true"> , </mo> <mn> 1 </mn> <mo> ≤ </mo> <mi> X </mi> <mo> ≤ </mo> <mn> 2000 </mn> <mo> ) </mo> </mrow> <annotation encoding="application/x-tex"> n,X(1 \leq n \leq 20, 1 \leq X \leq 2000) </annotation> </semantics> </math>n,X(1≤n≤20,1≤X≤2000)。
接下来输入 <math> <semantics> <mrow> <mi> n </mi> </mrow> <annotation encoding="application/x-tex"> n </annotation> </semantics> </math>n 个整数,每个整数不超过 <math> <semantics> <mrow> <mn> 100 </mn> </mrow> <annotation encoding="application/x-tex"> 100 </annotation> </semantics> </math>100。
输出格式
输出一个整数,表示能凑出 <math> <semantics> <mrow> <mi> X </mi> </mrow> <annotation encoding="application/x-tex"> X </annotation> </semantics> </math>X 的方案数。
样例输入
6 6
1 2 3 4 5 6
样例输出
4
题解
用二进制枚举子集
把某个数被选中置为 1,未被选中置为 0
外层循环遍历所有可能被选中的情况,从 00…00 到 11…11
内部循环遍历判断每一位是否被选中,如果该位被选中,则临时和加上该位数值
#include<iostream>
#include<algorithm>
using namespace std;
int main(){
int n,x;
int a[20+5];
int sum = 0;
cin>>n>>x;
for(int i=0;i<n;i++)
cin>>a[i];
for(int i=0;i<(1<<n);i++){
int tol = 0;
for(int j=0;j<n;j++){
if(i&(1 << j))
tol += a[j];
}
if(tol == x)
sum++;
}
cout<<sum;
return 0;
}