得到整数 X 二进制 递归

题目描述
某君有n个互不相同的正整数,现在他要从这n个正整数之中无重复地选取任意个数,并仅通过加法凑出整数X。求某君有多少种不同的方案来凑出整数X。
输入
第一行,输入两个整数n,X(1≤n≤20,1≤X≤2000)。
接下来输入n个整数,每个整数不超过100。
输出
输出一个整数,表示能凑出X的方案数。
样例输入
6 6
1 2 3 4 5 6
样例输出
4
提示
一共有 4 种方案:
6
1 5
1 2 3
2 4
看提示像子集生成问题,这道题目子集里的数和为X为限制条件。
可以看子集生成的代码上做调整

在这里插入图片描述
&
0&0=0; 0&1=0; 1&0=0; 1&1=1; 即:两位同时为“1”,结果才为“1”,否则为0

|
0|0=0; 0|1=1; 1|0=1; 1|1=1;即 :参加运算的两个对象只要有一个为1,其值为1。

^
0 ^ 0=0; 0 ^ 1=1; 1^ 0=1; 1^1=0; 即:参加运算的两个对象,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。

详细查看这里:非常详细
https://blog.csdn.net/weixin_43736974/article/details/84543970
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述在这里插入图片描述

#include <bits/stdc++.h>
using namespace std;
void print_subset(int n){
     for(int i=0; i< (1<<n); i++) {
   			//i:0~2^n,每个i的二进制数对应一个子集。
		for(int j=0;j<n;j++)   //打印一个子集,即打印i的二进制数中所有的1。
           if(i & (1<<j))     
               cout<< j << " ";
       	cout << endl;
    }
}
int main(){
    int n;
    cin>>n;           // n:集合中元素的总数量。
    print_subset(n);  // 打印所有的子集。
}

一、

#include <bits/stdc++.h>
using namespace std;
int n,x,a[25],cnt=0;
int main(){
	cin >>n >>x;
	for(int i=0;i<n;i++)
		cin >> a[i];
	for(int i=0;i<(1<<n);i++){  //(1<<n)=2^n i 的范围 (0~2^n-1)
		int sum=0;
		for(int j=0;j<n;j++){
			if(i&(1<<j))    //如果是1运行
				sum+=a[j];
		}
		if(sum==x)cnt++;
	}
	cout << cnt;
	return 0;
}

二、

递归的方法,跟权排列是不一样的,不要混淆,为小菜菜,解出来不容易,是从装载问题得到启发
不过看不懂的话打开软件自己调试一下哈!

#include <bits/stdc++.h>
using namespace std;
int n,x,sum=0,cnt=0;
int a[25],b[25]={0};
void dfs(int p,int q){
	if(q==x){
		cnt++;   //计算方案个数
		return;
	}
	else{
		for(int i=p;i<n;i++){
			if(b[i]==0){         //如果为0表示该下标对应的a数组的数字没有用过
				b[i]=1;
				dfs(i+1,q+a[i]);
				b[i]=0;     //回溯把它变为0;
			}
		}
	}
}
int main(){
	cin >>n >>x;
	for(int i=0;i<n;i++)
		cin >> a[i];
	dfs(0,0);
	cout << cnt;
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值