题目

某君有 <math> <semantics> <mrow> <mi> n </mi> </mrow> <annotation encoding="application&#47;x&#45;tex"> n </annotation> </semantics> </math>n 个互不相同的正整数,现在他要从这 <math> <semantics> <mrow> <mi> n </mi> </mrow> <annotation encoding="application&#47;x&#45;tex"> n </annotation> </semantics> </math>n 个正整数之中无重复地选取任意个数,并仅通过加法凑出整数 <math> <semantics> <mrow> <mi> X </mi> </mrow> <annotation encoding="application&#47;x&#45;tex"> X </annotation> </semantics> </math>X

求某君有多少种不同的方案来凑出整数 <math> <semantics> <mrow> <mi> X </mi> </mrow> <annotation encoding="application&#47;x&#45;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&#47;x&#45;tex"> n,X(1 \leq n \leq 20, 1 \leq X \leq 2000) </annotation> </semantics> </math>n,X(1n20,1X2000)

接下来输入 <math> <semantics> <mrow> <mi> n </mi> </mrow> <annotation encoding="application&#47;x&#45;tex"> n </annotation> </semantics> </math>n 个整数,每个整数不超过 <math> <semantics> <mrow> <mn> 100 </mn> </mrow> <annotation encoding="application&#47;x&#45;tex"> 100 </annotation> </semantics> </math>100

输出格式

输出一个整数,表示能凑出 <math> <semantics> <mrow> <mi> X </mi> </mrow> <annotation encoding="application&#47;x&#45;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;
}

返回目录,查看更多