递归与分治_整数的划分

#include <iostream>
#include <cstdio>
using namespace std;

/*
 * 求整数n的划分
 * n, m
 * 在整数n的所有划分中, 最大加数 n1<=m 的划分记做p(n, m);
 * 1. p(n, 1) = 1;                    (m == 1)
 * 2. p(n, n) = 1 + p(n, n-1);        (n == m)
 * 3. p(1, m) = 1;                    (n == 1)
 * 4. p(n, m) = p(n, m-1) + p(n-m, m) (n > m > 1)
 * 4的解释
 * n 关于m的划分
 *
 * m + div(n4), m + div(n3)..
 * m-1 + div(n1), m-1 + div(n2) ...
 * m-2 ...
 * 1 + 1 + 1....(m个1)
 */

int p(int n, int m)
{
    if(m == 1 || n == 1)  return 1;
    else if(n == m) return 1+p(n, n-1);
    else if(m >= n) return p(n,n);
    else return p(n , m-1) + p(n-m, m);
}

int main()
{
    //计算n的划分,即为p(n, n);
    cout << p(6,6) << endl;;
    return 0;
}

时间: 2024-10-16 22:22:11

递归与分治_整数的划分的相关文章

重拾算法之路——递归与分治基础

***************************************转载请注明出处:http://blog.csdn.net/lttree******************************************** 这个周末家里有点事,回了趟家,就断了一些学习计划.. 抓紧补上! 第一个算法--递归与分治 都知道,分治算法基本思想是 将一个难以直接解决的问题,分割成一些规模小的相同问题,以便各个击破,分而治之, 这样,我们就可以将一个复杂的算法,类型不变,规模越来越小,最终

递归的逻辑(3)——递归与分治

递归和分治天生就是一对好朋友.所谓分治,顾名思义,就是分而治之,是一种相当古老的方法. 在遥远的周朝,人们受生产力水平所限,无法管理庞大的土地和众多的人民,因此采用了封邦建国的封建制度,把土地一层一层划分下去,以达到分而治之的目的,这也许是最古老的分治法了: 分治的步骤 正像分封土地一样,分治法的目的就是为了把无法解决的大问题分解成若干个能够解决小问题.通常来说,分治法可以归纳为三个步骤: 1. 分解,将原问题分解成若干个与原问题结构相同但规模较小的子问题: 2. 解决,解决这些子问题.如果子问

五大常见算法策略——递归与分治策略

摘要:递归与分治策略是五大常见算法策略之一,分治策略的思想就是分而治之,即先将一个规模较大的大问题分解成若干个规模较小的小问题,再对这些小问题进行解决,得到的解,在将其组合起来得到最终的解.而分治与递归很多情况下都是一起结合使用的,能发挥出奇效(1+1>2),这篇文章我们将先从递归说起,再逐渐向分治过渡,主要讲解方式是通过9个例题来说明问题的,问题都是根据难度由简到难,由浅入深,对递归与分治能有个大概的了解雏形,当然最重要还是要做大量练习才能掌握. 1.递归 我们第一次接触递归一般都是在初学C语

整数的划分

整数的分划问题. 如,对于正整数n=6,可以分划为: 6 5+1 4+2, 4+1+1 3+3, 3+2+1, 3+1+1+1 2+2+2, 2+2+1+1, 2+1+1+1+1 1+1+1+1+1+1+1 现在的问题是,对于给定的正整数n,编写算法打印所有划分. 用户从键盘输入 n (范围1~10) 程序输出该整数的所有划分. 这个题目我用的递归,但是思路和我网上看到的不一样,貌似更简单一点, /** * 5=1+1+1+1+1     4=1+1+1+1 3=1+1+1 2=1+1    

ACM:递归与分治,最大连续和,O(n3), O(n2), O(nlogn), O(n) 算法。

题目,求一个连续的数组,最大连续和. (一)O(n3)算法: 利用穷举法的思想,这种方法的效率最差. 代码如下: #include <iostream> #include <cstdlib> #include <ctime> #include <cmath> using namespace std; const int MAXN = 1000; int A[MAXN], n; int maxsum(int *A, int n) { int beat = A[

快速排序(递归与分治的思想)

快排具有递归和分治的思想,实现步骤如下. 第一步:对数组A中的第一个元素x执行操作,使得数组变成新的数组B,B中C段表示小于x的元素,D段表示大于x的元素 第二步:把C段,D段,当成2个独立的数组,然后对这2个数组执行类似于第一步中A的操作 第三步:这样B和D数组又同样被分成了三部分,依次类推反复执行相同的操作. 代码: #include<iostream> using namespace std; void swap(int &a,int &b) { int c; c=a;

五类常见算法小记 (递归与分治,动态规划,贪心,回溯,分支界限法)

近日复习了一些算法知识,小记于此 递归与分治法 直接或间接地调用自身的算法称为递归算法. 递归是算法设计与分析中常用的一种技术,描述简单且易于理解. 分治法的设计思想是将一个规模为n难以解决的问题分解为k个规模较小的子问题,这些子问题相互独立且与原问题相同. 递归地解这些子问题,然后将各子问题的解合并得到原问题的解. 典型例子:Fibonacci数列,阶乘,Hanoi塔:二分法搜索.快速排序.合并排序. 动态规划法 动态规划过程是:根据当前(阶段)状态,采取相应的决策,引起状态的转移.如下图,一

浅谈递归和分治

今天要谈论的话题主要是递归和分治.为什么要将分治和递归放在一起说?很简单,因为这两兄弟几乎不分家.就我所见过的,任何用到分治思想的算法就没有不用递归的.(如果某位朋友知道例外的,请不吝赐教.) 所谓递归,就是自己调用自己.第一步是设置基值条件用于方法的返回,否则方法将不停的自调用,直到程序崩溃.第二部是缩小问题域的范围并调用自己来求解,直到范围缩小到触发基值条件为止. 所谓分治,即分而治之.它也分两步:一,把一个大的问题域分解为小的问题域.二,对每个小的问题域按步骤一办理.(单从这句话来说,我们

递归与分治策略(一)---算法设计与分析

递归与分治策略(一) 简而言之,递归就是自己调用自己. 递归算法:直接或者间接地调用自身的算法. 递归函数:用函数自身给出定义的函数. 注意:每个递归函数都必须有非递归定义的初始值,以确保递归函数完成计算. 下面通过两个例子来介绍递归的特点 例1 阶乘函数 阶乘函数递归地定义为: n!=1   (n=0) 或者 n!=n(n-1)!  (n>0) 下面用一段简单的Java代码实现 这里是递归实现: public static int facterial(int n) { if (n == 0)