`
lknh
  • 浏览: 25423 次
  • 性别: Icon_minigender_1
  • 来自: 广西
社区版块
存档分类
最新评论

论坛开到的一个数字拆分算法,感觉不错

阅读更多
http://www.iteye.com/topic/963980#1983213
题目
将任一个数字进行拆解,例如:  
 
3 = 2+1 = 1+1+1 所以3有三種拆法  
4 = 3 + 1 = 2 + 2 = 2 + 1 + 1 = 1 + 1 + 1 + 1 共五種  
5 = 4 + 1 = 3 + 2 = 3 + 1 + 1 = 2 + 2 + 1 = 2 + 1 + 1 + 1 = 1 + 1 +1 +1 +1 共七种  
 
 
随便给一个数字,对其进行拆解,并打印可拆解情况和拆解结果数。 
动态规划思想:
这个可以用动态规划来做:
状态:dp[x][y]表示将x拆分成的最大值为y的方法总数。
过程:dp[x][y] = dp[x-y][1] + dp[x-y][2] + … +dp[x-y][y];
结果:result = dp[n][1] + dp[n][2] + dp[n][3] + … + dp[n][n];

递归思想:
就是走楼梯算法:
给定n阶楼梯,可以一次跨1阶、2阶……k阶(k<=n,问共有多少走法,并记录每种走法
递归公式:  f(n) = f(n-1) + f(n-2) + f(n-3)+……+f(n-k)   n>=1
private void climb(int n, int step,List<int> steps)
        {
            if (step > n)
                return;

            steps.Add(step);

            if (n == step)
            {
                //当剩余楼梯的阶数等于第一步所跨的阶数
                //则到达最后一阶楼梯,此时为其中一种走法

                //记录每次走法
                this.count++;
              print(steps);

            }
            else
            {
                //如果没有达到最后一层,则递归剩余楼梯的走法
                //此时,第一可跨最大阶数由允许所跨最大阶数和剩余楼梯阶数的较小值决定

                for (int i = 1; i <= stemp&& i <= n - step; i++)
                {
                    //递归剩余楼梯第一步的每种走法
                    climb(n - step, i);

                    //退出递归时,清除剩余楼梯的走法
                    //以记录新的走法
                     list.RemoveAt(list.Count - 1);
                }

            }

        }

测试结果 :n=5,step=5时,共有16种走法:
1 1 1 1 1
1 1 1 2
1 1 2 1
1 1 3
1 2 1 1
1 2 2
1 3 1
1 4
2 1 1 1
2 1 2
2 2 1
2 3
3 1 1
3 2
4 1
5

这是考虑顺序的,你上面的就更简单了,不考虑顺序,放进set对象里过滤一下就可以了
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics