/-------f(n - 1, m) + f(n - 1, m - n) (m>=n>1)
f(n,m) = --------1 (n=1)
\------f(m, m) (n>m)
//输入两个整数 n 和 m,从数列1,2,3.......n 中 随意取几个数,
//使其和等于 m ,要求将其中所有的可能组合列出来.#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <map.h>
typedef map<int, map<int, int> > MAP_TYPE;
int GetMNResult(const int m, const int n, MAP_TYPE & mapCollected)
{
int iResult;
MAP_TYPE::iterator iIterMap;
map<int, int> mapTmp;
map<int, int>::iterator iIterTmp;
iIterMap = mapCollected.find(m);
if(iIterMap != mapCollected.end()) {
iIterTmp = iIterMap->second.find(n);
if(iIterTmp != iIterMap->second.end()) {
return mapCollected[m][n];
}
}
if(n <= 0) {
iResult = 0;
goto GetMNResultExit;
}
if(m <= 1) {
iResult = 1;
goto GetMNResultExit;
}
if((1 + n) * n / 2 < m ) {
iResult = 0;
goto GetMNResultExit;
}
if(m < n) {
iResult = GetMNResult(m, m, mapCollected);
goto GetMNResultExit;
}
iResult = GetMNResult(m, n - 1, mapCollected) + GetMNResult(m - n, n - 1, mapCollected);
GetMNResultExit:
mapCollected[m][n] = iResult;
return iResult;
}
static int GetResult(const int m, const int n)
{
static MAP_TYPE mapData; //去除那些已经计算过的m,n再次进行重复计算
return GetMNResult(m, n, mapData);
}
int main(int argc, char ** argv)
{
int iResult;
int m, n;
m = 10;
n = 5;
int iLoop;
for(iLoop = 0; iLoop < 20; iLoop++) {
m = iLoop;
iResult = GetResult(m, n);
printf("m:%d; n=%d; iResult:%d\n", m, n, iResult);
}
return 0;
}