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

原创 2013年10月19日 11:33:33

来自: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


相关文章推荐

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

输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数, 使其和等于 m ,要求将其中所有的可能组合列出来. /** * 输入两个整数 n 和 m,从数列1,...

输入两个整数 n 和 m,从数列1,2,3.......n 中随意取几个数,使其和等于 m ,要求将其中所有的可能组合列出来.

#include #include #include #include using namespace std; int length; void PrintSolutions(int *f...

【微软100题】2010年中兴面试题 编程求解: 输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数, 使其和等于 m

package test; /** * 2010年中兴面试题 编程求解: 输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数, 使其和等于 m * ,要求将其中所有的可...

输入两个整数 n 和 m ,从数列 1 , 2 , 3.......n 中随意取几个数 ,使其和等于 m

转载自:http://blog.sina.com.cn/s/blog_7571423b01016707.html 编程求解:输入两个整数 n 和 m ,从数列 1 , 2 , 3.......n...

《动态规划》 输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数, 使其和等于 m

这是一道中兴的面试题 题目: 输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数, 使其和等于 m ,要求将其中所有的可能组合列出来. ...

动态规划——5 输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数, 使其和等于 m

这是一道中兴的面试题 题目: 输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数, 使其和等于 m ,要求将其中所有的可能组合列出来....

输入两个整数n和m,从数列1,2,3....n中随意取几个数,使其和等于m

问题描述:        输入两个整数n和m,从数列1,2,3,......n中随意取几个数,使其和等于m,要求将其中所有的可能组合列出来。 问题分析:     此题类似于0-1背包问题,设原问...
  • seu2hit
  • seu2hit
  • 2013年03月26日 13:32
  • 456

一个中兴的面试题,输入两个数n和m,从数列1,2,3……n中随意取几个数,使其和等于m,要求将其中所有组合列出来编程求解(c语言递归函数分解法)

原题目:输入两个数n和m,从数列1,2,3……n中随意取几个数,使其和等于m,要求将其中所有组合列出来编程求解 c语言解法分析:            先判定n和m的大小,如果m小于n,则只需从1...

从数列1,2,3.......n 中 随意取几个数,使其和等于 m

其实是个背包问题。 void FindSum(int sum, int n)//1到n和为m的所有组合 { static vector l; if(n...
  • cxllyg
  • cxllyg
  • 2012年05月21日 16:38
  • 1856

从数列1,2,3,......,n中随意取出几个数,使其和等于m

问题描述:     输入两个整数n和m,从数列1,2,3,.......n中随意去几个数,使其和等于m,要求将其中所有可能的组合列出来。 解决思路:     这个问题其实是背包问题的变形,给...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:算法习题21:输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,找出和为m
举报原因:
原因补充:

(最多只允许输入30个字)