算法习题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 中 随意取几个数, 使其和等于 m

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

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

编程求解: 输入两个整数 n 和 m,从数列 1,2,3.......n 中 随意取几个数, 使其和等于 m ,要求将其中所有的可能组合列出来. 思路: 从小到大 依次拼凑 后...
  • wangdd_199326
  • wangdd_199326
  • 2017年09月02日 18:47
  • 197

输入两个整数n和m,从数列1,2,3,……n中随意取几个数,使其和等于m。要求将所有的可能组合列出来。实际上就是一个背包问题

100题之21题:编程求解,输入两个整数n和m,从数列1,2,3,……n中随意取几个数,使其和等于m。要求将所有的可能组合列出来。实际上就是一个背包问题。 求解思路: 1.首先判断,如果n>m,则...
  • luyuncsd123
  • luyuncsd123
  • 2014年07月19日 02:47
  • 2228

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

本题的关键在随意取几个数, 因此和以前解过的true or false问题思路一样.网上一搜才发现这是一类问题, 称01背包问题 我们可以使用递归来列举出所有的排列组合情况,共有2的n次方中...
  • haoyuedangkong_fei
  • haoyuedangkong_fei
  • 2016年07月12日 15:43
  • 310

从数列1, 2, 3, ... , n 中 随意取几个数,使其和等于sum. [No. 24]

问题: 输入两个整数 n 和 sum,从数列1, 2, 3, ... , n 中 随意取几个数,使其和等于 sum,要求将其中所有的可能组合列出来. 比如n = 5, sum  = 8, 那么...
  • beiyeqingteng
  • beiyeqingteng
  • 2011年12月28日 07:48
  • 2640

Java求解,输入两个整数n和m,从数列1,2,3,……n中随意取几个数,使其和等于m。要求将所有的可能组合列出来(背包动态规划问题求解)

输入两个整数n和m,从数列1,2,3,……n中随意取几个数,使其和等于m。要求将所有的可能组合列出来。 之前看到有同学写该问题的Javab...
  • u010037324
  • u010037324
  • 2014年09月27日 15:55
  • 1891

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

#include #include using namespace std; //输入两个整数n 和m,从数列1,2,3.......n 中随意取几个数, //使其和等于m ,要求将其中所有的...
  • fuqiaoyimeng
  • fuqiaoyimeng
  • 2014年09月22日 22:27
  • 1263

每日一练——从长度为n的数组里选出m个数使和为固定值sum

这个问题是我从leetcode上一道问题所想到的,原题:如果是从数组中选出2个数相加使之成为固定的数sum,这当然很简单,把数组中的数字遍历一遍,判断另一个数字是否也在数组中即可。代码如下。 ...
  • a987073381
  • a987073381
  • 2016年07月24日 22:47
  • 3605

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

本文转自:http://blog.csdn.net/wuzhekai1985/article/details/6728657   问题描述:输入两个整数n和m,从数列1,2.......n中随意取几个...
  • lx198986611235
  • lx198986611235
  • 2013年12月24日 21:25
  • 662

【其他】【RQNOJ】数字组合

题目描述在N个数中找出其和为M的若干个数。先读入正整数N(1
  • liveas
  • liveas
  • 2010年07月14日 11:13
  • 904
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:算法习题21:输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,找出和为m
举报原因:
原因补充:

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