ylf13的专栏

life and programming

算法习题21:输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,找出和为m

来自:http://bbs.csdn.net/topics/350118968

2010年中兴面试题

编程求解:
输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,

使其和等于 m ,要求将其中所有的可能组合列出来.

————————————————————————————————————

这题其实就是一个背包问题,找出符合的物品,

一种方法是模拟背包放物品的过程,一个个的放,如果超出了,则回溯,否则继续放,相等时打印出结果

另一种方法可以采用类似动态规划的过程(这里可能说得不是很对吧) 原始问题是F(n,m)我们有两种可能,一个是放入,n,另一个是没有放入n,这两组解恰好合起来就是总的解,所以有F(n,m) = F(n-1,m-n) + F(n-1,m)

第一种方法模拟背包过程写起来比较麻烦,尤其边界判断问题!

第二种用递归方式可以很快得到结果!不过第一种函数调用次数比第二种稍微少些

上面这些考虑之后,这里还需要考虑,如果输入的m=0或者是负数 如何处理?

我这里模拟背包过程的代码很乱,大家就算了,别读了,直接看第二种方法,这种方法,解背包问题还是很方便的。

//============================================================================
// Name        : FindAllSumFactor.cpp
// Author      : YLF
// Version     :
// Copyright   : Your copyright notice
// Description : Hello World in C++, Ansi-style
//============================================================================

#include <iostream>
using namespace std;
#define MAX 100

int arr[MAX];
int index = 0;
void FindAllSumFactor(int cur, int sum, int n, int m);
void FindAllSumFactor2(int n, int m, int* arr, int index, int sum);
void FindAllSumFactor3(int cur, int sum, int n, int m);


int main() {
	int n = 0;
	int m = 0;
	cin>>n;
	cin>>m;
	arr[0]=1;
	index++;
	FindAllSumFactor(1,1,n,m);
//	FindAllSumFactor2(n, m, arr, index, 0);
	return 0;
}

void FindAllSumFactor(int cur, int sum, int n, int m){
	if(m==0){
		cout<<0;
		return;
	}
	if(sum>m){
		//这时候需要回溯,取出前一个值,丢弃
		//对再前一个值+1 继续
		if(--index<0)
			return;
		sum = sum - arr[index];
		if(--index<0)
			return;
		//这里cur++不可能大于N了,所以不用判断!
		arr[index] = arr[index]+1;
		cur = arr[index++];
		sum++;
		FindAllSumFactor(cur,sum,n,m);
	}
	else if(sum < m){
		if(cur+1 > n){
			//如果已经把最大的都加进来了,那么接下来就是回溯,增加再前一个的值
			index--;
			if(index<0)
				return;
			sum = sum - arr[index];
			index--;
			if(index<0)
				return;
			cur = arr[index];
			sum = sum-cur;
		}
			arr[index] = ++cur;
			sum = sum + cur;
			index++;

			FindAllSumFactor(cur, sum, n, m);
	}else{
		int i=0;
		for(i=0;i<index-1;i++)
			cout<<arr[i]<<"+";
		cout<<arr[i]<<"="<<m<<endl;
		//这时候恰好等于,所以去掉前一个值,不许要在继续下去了
		//对前一个值+1
		index--;
		if(index<0)
			return;

		sum = sum - arr[index];
		index--;
		if(index<0)
			return;
		cur = arr[index];
		cur++;
		arr[index] = cur;
		sum = sum + 1;
		index++;
		FindAllSumFactor(cur,sum,n,m);
	}
}

void FindAllSumFactor2(int n, int m, int* arr, int index, int sum){
	if(0 == m){
		int i =0;
		for(i=0;i<index-1;i++)
			cout<<arr[i]<<"+";
		cout<<arr[i]<<"="<<sum<<endl;
		return;
	}

	if(n-1>0)
		FindAllSumFactor2(n-1, m, arr, index, sum);
	if(n-1>=0 && n<=m){
		arr[index++] = n;
		sum += n;
		FindAllSumFactor2(n-1, m-n, arr, index, sum);
	}
}
例如:
9
13
1+2+3+7=13
1+2+4+6=13
1+3+4+5=13
1+3+9=13
1+4+8=13
1+5+7=13
2+3+8=13
2+4+7=13
2+5+6=13
3+4+6=13
4+9=13
5+8=13
6+7=13


阅读更多
个人分类: 算法
想对作者说点什么? 我来说一句

没有更多推荐了,返回首页

加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!
关闭
关闭