牛客网-和为sum的所有组合方案

#include<iostream>
#include<stack>
#include<algorithm>
#include<vector>
#include<string>
using namespace std;
/*********** 题目描述:
               输入两个整数 n 和 m,从数列1,2,3.......n 中随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来

************/
/******************** 分析思路: 采用深度优先搜索,一旦搜索到满足条件的组合,就输出 ********************/



int n, m, *a; 
vector<int> st; // 存储当前搜索方案的数字栈
// next_index: the next index to search the array
// cur_sum: 当前已经凑好的数值
//  为了剪纸,压缩搜索空间,设置 failure 表示当前搜索是否成功
bool failure = false;
bool dfs(int next_index, int cur_sum){
	// Step 2: 选中当前这个
	if (cur_sum + a[next_index] > m) // 因为已经升序排列了,所以后面的肯定不会满足要求,直接PASS,剪枝
	{
		return false;
	}
	else if (cur_sum + a[next_index] == m) // 因为已经升序排列了,所以后面的肯定不会满足要求,直接PASS,剪枝
	{
		st.push_back(a[next_index]);
		// 输出当前的方案
		for (int i = 0; i < (int)st.size(); i++)
		if (i != st.size() - 1)
			printf("%d ", st[i]);
		else
			printf("%d\n", st[i]);
		// 弹出最后的一个数字
		st.erase(st.end() - 1);
		// 设置标记
		return true;
	}
	st.push_back(a[next_index]);
	cur_sum += a[next_index];
	
	// Step 2: 确定下一步的搜索
	for (int i = next_index + 1; i < n; i++)
		dfs(i, cur_sum);

	// Step 3: 替换掉当前这个
	st.erase(st.end() - 1);
	cur_sum -= a[next_index];
	return false;
}

int main(int argc, char * argv[])
{
	// Input
	cin >> n >> m;
	a = new int[n]; //memset(a, 0, sizeof(int)*n);
	for (int i = 0; i < n; i++)
		a[i] = i + 1;

	// Process
	// 1. Sort
	sort(a, a + n);
	// 2. DFS
	for (int i = 0; i < n; i++)
		dfs(i, 0);

	return 0;
}

猜你喜欢

转载自blog.csdn.net/yangguangqizhi/article/details/84440115