中兴一道面试题

                /-------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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值