先注明学习博客的地址:(http://www.cnblogs.com/hoodlum1980/archive/2008/10/11/1308493.html

题目描述:任何正整数n都可以写成n=n1+n2+n3+……+nk;1<=n1,n2,n3,……nk<=n;这被称为整数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。

目标:求出n的划分个数,6的划分个数为11。

该博主给出了两种做法,我先研究一下第一种做法(递归法)

首先引入另一个概念:n的m划分,就是说划分必须满足:1<=n1,n2,n3,……nk<=m;这时我们就可以进行递归的分析了,求n的划分就是求f(n,n);

下面讨论f(n,m)的求法:

1.当n等于1时,只有一种划分;

2.当m等于1时,也只有一种划分;

3.当n=m时,

划分中含有m时,有一种划分;

划分中不含m时,有f(n,m-1)中划分;

综上:f(n,m)=1+f(n,m-1);

4.当n>m时,

划分中含有m时,即划分的形式是{m,{x1, x2, ..., xi}},则{x1, x2, ..., xi}个数为f(n-m,m);

划分中不含m时,即划分中的数都比m小,则划分个数为f(n,m-1);

综上划分f(n,m) =  f(n-m,m)+f(n,m-1);

通过对求f(n,m)的过程分析,可见可能出现n<m的情况。

5.当n<m时,f(n,m)= f(n,n);

综上:

f(n, m) =             1;                                         ( n = 1 or m = 1 )

f(n, n);                                 ( n < m )

1+ f(n, m - 1);                      ( n = m )

f(n - m, m) + f(n, m - 1);       ( n > m )

在写代码AC掉那道题之前,先体会一下,这个递归为什么能成为递归的经典例题吧。其实这题并不能很明显的找到缩小问题规模的入口,反而让你引入了一个过渡的变量,而且每一步的缩小都很勉强,只能从表达式上看出来。我之所以觉得这道题很好的原因是因为这种分类讨论是高中时经常用的,或许这才是活学活用的实例,是一种考虑问题的方式,是一种生活的态度,是智商带动情商的提高(扯远了&……&……&)。

正经事AC代码:

 #include<stdio.h>

 int F(int n, int m)
{
if (n == )
return ;
if (m == )
return ;
if (n < m)
return F(n, n);
if (n == m)
return F(n, m - ) + ;
if (n>m)
return F(n - m,m) + F(n, m - );
} int main()
{
int T;
scanf("%d",&T);
while (T--)
{
int n;
scanf("%d",&n);
printf("%d\n",F(n,n));
}
}

这里其实还是有一个问题的就是是否有必要加上记忆化搜索,经过测试发现是很有必要加的,测试的代码:

 #include<stdio.h>
#include<string.h> int a[][]; int F(int n, int m)
{
if (a[n][m] > ){
printf("Ues the a[%d][%d]\n",n,m);
return a[n][m];
}
if (n == )
return a[][m]=;
if (m == )
return a[n][]=;
if (n < m)
return a[n][n]=F(n, n);
if (n == m)
return a[n][m]=F(n, m - ) + ;
if (n>m)
return a[n][m]=F(n - m,m) + F(n, m - );
} int main()
{
int T;
scanf("%d",&T);
while (T--)
{
memset(a,-,sizeof(a));
int n;
scanf("%d",&n);
printf("%d\n",F(n,n));
}
}

好了,这题就到这儿了,至于博主提供了另一个方法,暂时就不讨论了。

整数划分——真正的递归经典例题(NYOJ——90)的更多相关文章

  1. NYOJ90 整数划分(经典递归和dp)

    整数划分 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 将正整数n表示成一系列正整数之和:n=n1+n2+…+nk,  其中n1≥n2≥…≥nk≥1,k≥1.  正 ...

  2. nyoj 90 整数划分

    点击打开链接 整数划分 时间限制:3000 ms  |  内存限制:65535 KB 难度:3 描述 将正整数n表示成一系列正整数之和:n=n1+n2+-+nk,  其中n1≥n2≥-≥nk≥1,k≥ ...

  3. C语言经典例题100

    C语言经典例题100 来源 http://www.fishc.com 适合初学者 ----------------------------------------------------------- ...

  4. NYOJ-571 整数划分(三)

    此题是个非常经典的题目,这个题目包含了整数划分(一)和整数划分(二)的所有情形,而且还增加了其它的情形,主要是用递归或者说是递推式来解,只要找到了递推式剩下的任务就是找边界条件了,我觉得边界也是非常重 ...

  5. nyoj_90_整数划分_201403161553

    整数划分 时间限制:3000 ms  |  内存限制:65535 KB 难度:3   描述 将正整数n表示成一系列正整数之和:n=n1+n2+…+nk, 其中n1≥n2≥…≥nk≥1,k≥1. 正整数 ...

  6. C语言中的经典例题用javascript怎么解?(一)

    C语言中的经典例题用javascript怎么解?(一) 一.1+2+3+……+100=?        <script type="text/javascript">  ...

  7. 整数划分 (区间DP)

    整数划分(四) 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近 ...

  8. 整数划分 Integer Partition(一)

    话说今天百度面试,可能是由于我表现的不太好,面试官显得有点不耐烦,说话的语气也很具有嘲讽的意思,搞得我有点不爽.Whatever,面试中有问到整数划分问题,回答这个问题过程中被面试官搞的不胜其烦,最后 ...

  9. POJ1664(整数划分)

    放苹果 Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 30894   Accepted: 19504 Description ...

随机推荐

  1. Myeclipse中启动tomcat 异常

    信息: Unable to find org.hibernate.search.event.FullTextIndexEventListener on the classpath. Hibernate ...

  2. java入门了解06

    1.进程 :     (一)正在执行的程序称作为一个进程. 进程负责了内存空间的划分. (二)问题: windows号称是多任务的操作系统,那么windows是同时运行多个应用程序吗? 从宏观的角度: ...

  3. js 禁止用户使用Ctrl+鼠标滚轮缩放网页

    为什么会有人会使用ctrl+鼠标滚轮缩放网页?坚决禁止! <html> <head> <title>测试</title> <script lang ...

  4. ZOJ 2724 Windows Message Queue (二叉堆,优先队列)

    思路:用优先队列 priority_queue,简单 两种方式改变队列 的优先级 (默认的是从大到小) #include<iostream> #include<queue> # ...

  5. 一個在WCF學習中的小教訓(本人非科班菜鳥,此經驗無參考價值,衹是自己的經驗記錄)

    1.关于“ServiceHost 仅支持类服务类型”的解决:   Service属性必须执行,不是接口. 改为下图所示: 解决! (注:按朱哥的方法WCF已经可以通信---截至今天的11:11(例子在 ...

  6. leetcode 6 ZigZag Conversion(水题)

    就是简单的模拟一下就可以了.但是我一开始是用一个二维char数组来存的,这样在最终扫全体时会扫很多空的位置,浪费了很多时间,所以就time limit error了. 所以改进一下就用string数组 ...

  7. stl_pair.h

    stl_pair.h // Filename: stl_pair.h // Comment By: 凝霜 // E-mail: mdl2009@vip.qq.com // Blog: http://b ...

  8. 【遍历二叉树】12往二叉树中添加层次链表的信息【Populating Next Right Pointers in Each Node II】

    本质上是二叉树的层次遍历,遍历层次的过程当中把next指针加上去. ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ ...

  9. NYOJ-127 快速求幂,最小生成树

    #include"iostream" using namespace std; int kuaisuqiumo(int a,int b,int c){ ; a = a % c; ) ...

  10. ACM学习历程—HDU 5025 Saving Tang Monk(广州赛区网赛)(bfs)

    Problem Description <Journey to the West>(also <Monkey>) is one of the Four Great Classi ...