数组中任意几个元素的和是否等于m(递归)

62 篇文章 0 订阅
48 篇文章 2 订阅

1.问题描述


已知一个一维数组,又已知一个整数m。如果能使数组a中几个元素之和等于m,则输出Yes,否则输出No。

样例输入:3

                   3 1 6

                   6

样例输出:Yes


2.算法分析


其实这道题目意思就是,假定数组为nums,就是让我们判断能否从数组nums取任意数使其和为m

对于nums中任意元素nums[n]只有取或者不取两种情况:

1.取nums[n]

问题就要转化为:对于一个确定的数组nums[1...n-1]和一个确定的数m-nums[n],判断能否使数组nums[1....n-1]中任意几个元素的和为m-nums[n]即可。

2.不取nums[n]

此时问题转化为:对于一个已确定的数组nums[1..n]和一个确定的数m,判断能否使数组nums[1...n-1]中任意几个元素之和为m。


3.源代码


#include<iostream>
using namespace std;

int nums[101];
int n;	//数组元素个数
int m;	//数组中存在n个元素和为m
bool flag;

void sum(int n,int m)   //求数组中是否存在一些元素和等于m
{
	if(nums[n] == m) flag = true;  //假设数组的最后一个元素等于和m,将flag变量置为true
	else if(n == 1) return;    //搜索完了整个数组返回
	else
	{
		sum(n-1,m-nums[n]);   //说明取了nums[n]元素
		sum(n-1,m);	//说明没有取nums[n] 
	} 
} 

int main()
{
	cin>>n;
	for(int i =1;i<=n;i++)
	{
		cin>>nums[i]; 
	}
	cin>>m;
	flag = false; //初始时,将flag置为false,当找到某些元素和为m的时候在sum函数中flag的值将改变
	sum(n,m);
	if(flag)
	cout<<"Yes"<<endl;
	else
	cout<<"No"<<endl;
	return 0;
}

 

好的,这是一个关于递归算法的问题。根据您的要求,我可以给您提供一个C++的递归算法实现,如下所示: ```c++ #include <iostream> using namespace std; bool isSubsetSum(int arr[], int n, int sum) { // 如果 sum 为 0,则说明已经找到了和为 m 的子集,返回 true。 if (sum == 0) return true; // 如果 n 为 0,但 sum 不为 0,则说明已经遍历完了数组元素,但仍然没有找到和为 m 的子集,返回 false。 if (n == 0 && sum != 0) return false; // 如果 arr[n-1] 大于 sum,则不包括 arr[n-1],递归处理前 n-1 个元素。 if (arr[n-1] > sum) return isSubsetSum(arr, n-1, sum); // 返回 isSubsetSum 的两个可能结果:包含 arr[n-1] 或不包含 arr[n-1]。 return isSubsetSum(arr, n-1, sum) || isSubsetSum(arr, n-1, sum-arr[n-1]); } int main() { int n, arr[25], m; cin >> n; for (int i = 0; i < n; i++) cin >> arr[i]; cin >> m; // 调用 isSubsetSum 函,并输出结果。 if (isSubsetSum(arr, n, m)) cout << "YES" << endl; else cout << "NO" << endl; return 0; } ``` 该算法使用了递归的思想,通过不断缩小数组范围,判断数组是否存在和为m的子集。具体实现过程如下: - 如果 sum 为 0,则说明已经找到了和为 m 的子集,返回 true。 - 如果 n 为 0,但 sum 不为 0,则说明已经遍历完了数组元素,但仍然没有找到和为 m 的子集,返回 false。 - 如果 arr[n-1] 大于 sum,则不包括 arr[n-1],递归处理前 n-1 个元素。 - 返回 isSubsetSum 的两个可能结果:包含 arr[n-1] 或不包含 arr[n-1]。 希望这个算法对您有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值