整数划分——真正的递归经典例题(NYOJ——90)
先注明学习博客的地址:(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)的更多相关文章
- NYOJ90 整数划分(经典递归和dp)
整数划分 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 将正整数n表示成一系列正整数之和:n=n1+n2+…+nk, 其中n1≥n2≥…≥nk≥1,k≥1. 正 ...
- nyoj 90 整数划分
点击打开链接 整数划分 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 将正整数n表示成一系列正整数之和:n=n1+n2+-+nk, 其中n1≥n2≥-≥nk≥1,k≥ ...
- C语言经典例题100
C语言经典例题100 来源 http://www.fishc.com 适合初学者 ----------------------------------------------------------- ...
- NYOJ-571 整数划分(三)
此题是个非常经典的题目,这个题目包含了整数划分(一)和整数划分(二)的所有情形,而且还增加了其它的情形,主要是用递归或者说是递推式来解,只要找到了递推式剩下的任务就是找边界条件了,我觉得边界也是非常重 ...
- nyoj_90_整数划分_201403161553
整数划分 时间限制:3000 ms | 内存限制:65535 KB 难度:3 描述 将正整数n表示成一系列正整数之和:n=n1+n2+…+nk, 其中n1≥n2≥…≥nk≥1,k≥1. 正整数 ...
- C语言中的经典例题用javascript怎么解?(一)
C语言中的经典例题用javascript怎么解?(一) 一.1+2+3+……+100=? <script type="text/javascript"> ...
- 整数划分 (区间DP)
整数划分(四) 时间限制:1000 ms | 内存限制:65535 KB 难度:3 描述 暑假来了,hrdv 又要留学校在参加ACM集训了,集训的生活非常Happy(ps:你懂得),可是他最近 ...
- 整数划分 Integer Partition(一)
话说今天百度面试,可能是由于我表现的不太好,面试官显得有点不耐烦,说话的语气也很具有嘲讽的意思,搞得我有点不爽.Whatever,面试中有问到整数划分问题,回答这个问题过程中被面试官搞的不胜其烦,最后 ...
- POJ1664(整数划分)
放苹果 Time Limit: 1000MS Memory Limit: 10000K Total Submissions: 30894 Accepted: 19504 Description ...
随机推荐
- Qt之任务栏系统托盘图标
转自 --> http://blog.csdn.net/qivan/article/details/7506306 托盘图标,一个自己脑子出现很久的词,可惜自己都没动手去实现.最近看见的,听见 ...
- Oracle视图的使用
--视图的语法 create [ or replace ] [NO Force | Force] View schema.view_name--视图名称 [(alias,...)inline_cons ...
- css 动画的例子
1. [代码] <!DOCTYPE HTML><html><head><meta charset="utf-8"><tit ...
- Codeforces 897C Nephren gives a riddle:模拟【珂学】
题目链接:http://codeforces.com/contest/897/problem/C 题意: 给你一些字符串: A: [What are you doing at the end of t ...
- GW知识点
1.取值: protected void Button1_Click(object sender, EventArgs e) { string str = ""; foreach ...
- MVC中使用showModalDialog
1.mvc中使用模态对话框用于修改数据,如果第一次修改过后刷新页面,第二次修改时显示内容依然是第一次修改之前的,这里用js中的Math.Random()解决 Views: <%: Html.Ac ...
- js和jquery 两种写法 鼠标经过图片切换背景效果
这个是javascript的写法 <img src="res/img/shop-c_32.jpg" alt="" onmouseover="th ...
- python-字典和json
Python的字典和JSON在表现形式上非常相似 #这是Python中的一个字典 dic = { 'str': 'this is a string', 'list': [1, 2, 'a', 'b'] ...
- Python基础-修改excel中内容
from xlutils.copy import copy import xlrd import os #1.打一要修改的excel #2.再打开另一个excel #3.把第一个excel里面修改东西 ...
- HashMap,Hashtable,TreeMap ,Map
package com.wzy.list; import java.util.HashMap; import java.util.Hashtable; import java.util.Iterato ...