整数划分

时间限制:3000 ms  |  内存限制:65535 KB
难度:3
 
描述
将正整数n表示成一系列正整数之和:n=n1+n2+…+nk, 
其中n1≥n2≥…≥nk≥1,k≥1。 
正整数n的这种表示称为正整数n的划分。求正整数n的不 
同划分个数。 
例如正整数6有如下11种不同的划分: 
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。

 
输入
第一行是测试数据的数目M(1<=M<=10)。以下每行均包含一个整数n(1<=n<=10)。
输出
输出每组测试数据有多少种分法。
样例输入
1
6
样例输出
11
来源
[苗栋栋]原创
上传者
苗栋栋
 

此题可以用递归和动态规划两种方法来解决,首先介绍动态规划的,数组dp[N][M]表示N为被划分数,M为划分数的最大值,此题M==N,故即求dp[N][N];

1>状态转移方程:

dp[N][M]=dp[N][M-1]+dp[N-M][M];

该怎样理解呢?这里分两步:

Step 1:所划分的最大数不包括M,即每个划分数都是小于M的,此时总数为dp[N][M-1].

Step 2:所划分的最大数包括M,那么这一步被划分数就应该减去一个M,此时总数为dp[N-M][M].

到这里就是完整的思路了,应该注意的是上面的划分,划分数里有重复的数,那么如果要求划分数没有重复的呢,该怎样求呢?

这里的状态转移方程和上面就有点细微区别了.先来看看方程:

2>dp[N][M]=dp[N][M-1]+dp[N-M][M-1];

其实联系1中的步骤就不难理解了,同样分为两步:

Step 1:所划分的最大数不包括M,即每个划分数都是小于M的,此时总数也是dp[N][M-1].

Step 2:所划分的最大数包括M,那么划分就的相应的减去M,注意到不能重复,即M划分数出现的次数只能为1.所以M就得换成M-1了,即dp[N-M][M-1].

3>在拓展一下,要是划分的个数为确定的数呢?即dp[N][K].表示N被划分成K个数.

这时状态转移方程就为

dp[N][K]=dp[N-K][K]+dp[N-1][K-1].

应该这样理解:

Step 1:被划分的K个数中不包括1,那么就应该先自动的为其分配1,K个数共N-K,剩下的数自由分配,总能保证其值大于2,即dp[N-K][K].

Step 2:存在一个数为1的情况,此时剩下的N-1分给K-1个数,即dp[N-1][K-1].

代码如下:

 #include <stdio.h>
#include <string.h>
int dp[][];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int i,j,n;
memset(dp,,sizeof(dp));
scanf("%d",&n);
for(i=;i<=n;i++)
{
for(j=;j<=n;j++)
{
if(i>j)
dp[i][j]=dp[i-j][j]+dp[i][j-];
else if(i==j)
dp[i][j]=dp[i][j-]+;
else if(i<j)
dp[i][j]=dp[i][i];
}
}
printf("%d\n",dp[n][n]);
}
return ;
}

下面来介绍递归的方法:

整数划分问题是算法中的一个经典命题之一,有关这个问题的讲述在讲解到递归时基本都将涉及。所谓整数划分,是指把一个正整数n写成如下形式:

n=m1+m2+...+mi; (其中mi为正整数,并且1 <= mi <= n),则{m1,m2,...,mi}为n的一个划分。

如果{m1,m2,...,mi}中的最大值不超过m,即max(m1,m2,...,mi)<=m,则称它属于n的一个m划分。这里我们记n的m划分的个数为f(n,m);

例如当n=4时,他有5个划分,{4},{3,1},{2,2},{2,1,1},{1,1,1,1};

注意4=1+3 和 4=3+1被认为是同一个划分。

该问题是求出n的所有划分个数,即f(n, n)。下面我们考虑求f(n,m)的方法;

1.递归法:

根据n和m的关系,考虑以下几种情况:

(1)当n=1时,不论m的值为多少(m>0),只有一种划分即{1};

(2) 当m=1时,不论n的值为多少,只有一种划分即n个1,{1,1,1,...,1};

(3) 当n=m时,根据划分中是否包含n,可以分为两种情况:

(a). 划分中包含n的情况,只有一个即{n};

(b). 划分中不包含n的情况,这时划分中最大的数字也一定比n小,即n的所有(n-1)划分。

因此 f(n,n) =1 + f(n,n-1);

(4) 当n<m时,由于划分中不可能出现负数,因此就相当于f(n,n);

(5) 但n>m时,根据划分中是否包含最大值m,可以分为两种情况:

(a). 划分中包含m的情况,即{m, {x1,x2,...xi}}, 其中{x1,x2,... xi} 的和为n-m,因此这种情况下

为f(n-m,m)

(b). 划分中不包含m的情况,则划分中所有值都比m小,即n的(m-1)划分,个数为f(n,m-1);

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

综上所述:

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)

代码如下:

 #include <stdio.h>
int f(int n,int m) // fun(n, m)表示将整数 n 划分为最大数不超过 m 的划分
{
if(n==||m==)
return ;
else if(m>n)
return f(n,n);
else if(m==n)// 此时也是两部分,如果含有 m 则只有一种只含有 m 的划分,如果不含有 m 则转化为最大数不超过 m-1 的划分
return f(n,m-)+;
else if(m<n) // 此时将问题转化为两部分 1.划分中含有 m; 2.划分中不含 m
return f(n,m-)+f(n-m,m);
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int n;
scanf("%d",&n);
printf("%d\n",f(n,n));
}
return ;
}

nyoj_90_整数划分_201403161553的更多相关文章

  1. 51nod p1201 整数划分

    1201 整数划分 基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题 将N分为若干个不同整数的和,有多少种不同的划分方式,例如:n = 6,{6} {1,5} {2, ...

  2. 2014北大研究生推免机试(校内)-复杂的整数划分(DP进阶)

    这是一道典型的整数划分题目,适合正在研究动态规划的同学练练手,但是和上一个随笔一样,我是在Coursera中评测通过的,没有找到适合的OJ有这一道题(找到的ACMer拜托告诉一声~),这道题考察得较全 ...

  3. 整数划分 (区间DP)

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

  4. nyoj 90 整数划分

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

  5. 整数划分 Integer Partition(二)

    本文是整数划分的第二节,主要介绍整数划分的一些性质. 一 先来弥补一下上一篇文章的遗留问题:要求我们所取的 (n=m1+m2+...+mi )中  m1 m2 ... mi连续,比如5=1+4就不符合 ...

  6. 整数划分 Integer Partition(一)

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

  7. 51nod1201 整数划分

    01背包显然超时.然后就是一道神dp了.dp[i][j]表示j个数组成i的方案数.O(nsqrt(n)) #include<cstdio> #include<cstring> ...

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

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

  9. BZOJ1263: [SCOI2006]整数划分

    1263: [SCOI2006]整数划分 Time Limit: 1 Sec  Memory Limit: 162 MBSubmit: 677  Solved: 332[Submit][Status] ...

随机推荐

  1. 国庆集训 || Wannafly Day4

    链接:https://www.nowcoder.com/acm/contest/205#question 一场题面非常 有趣 但是题目非常 不友好的比赛 QAQ L.数论之神   思维(?) 题意:求 ...

  2. C01 C语言基础

    目录 C语言简史及特点 C语言开发环境 C语言程序结构 C语言基本输入输出函数 编译 软件类型 C语言简要及特点 什么是计算机语言 计算机语言是用于人与计算机之间通讯的语言. 计算机遵照接收到的计算机 ...

  3. 第1节 flume:11、flume的failover机制实现高可用

    1.4 高可用Flum-NG配置案例failover 在完成单点的Flume NG搭建后,下面我们搭建一个高可用的Flume NG集群,架构图如下所示: 图中,我们可以看出,Flume的存储可以支持多 ...

  4. shell脚本,实现奇数行等于偶数行。

    请把如下字符串stu494e222fstu495bedf3stu49692236stu49749b91转为如下形式:stu494=e222fstu495=bedf3stu496=92236stu497 ...

  5. Respond.js-----20150415

    Respond.js让IE6-8支持CSS3 Media Query. Bootstrap里面就引入了这个js文件,从名字看出来是自适应的兼容.打开IE看了一下,效果挺好的,自适应的效果挺好的.Res ...

  6. history.pushState 实现浏览器页面不刷新修改url链接

    最近遇到了在不刷新页面的情况下修改浏览器url链接的需求,遂求助于万能的度娘,最终通过history.pushState()完美解决问题.现在将我理解的一些内容分享一下,不对的地方欢迎大家指出. 在使 ...

  7. Fortran学习记录3(选择语句)

    流程控制语句 if的基本用法 if-else语句块 多重判断if-elseif语句 if语句嵌套 Select case语句 Goto语句 PAUSE CONTINUE STOP 流程控制语句 if的 ...

  8. Wash!!(HDU_6000)

    传送门:Wash! 题意:有n台洗衣机,m台烘干机,给出了每台机器处理意见衣服的时间,而且没见机器同时只能处理一件衣服.问如何选择机器才能使洗完衣服的时间最短. 思路:建两个优先队列,一个表示洗衣机, ...

  9. MySQL 查询优化之 Multi-Range Read

    MySQL 查询优化之 Multi-Range Read MRR的工作原理 MRR开启与关闭 使用MRR示例 参考文档 在存储引擎中未缓存的大表,使用辅助索引的range scan检索数据, 可能会导 ...

  10. 五分钟入门 Dingo API

    基于 https://laravel-china.org/doc... 文档更简洁的描述Dingo,直戳重点,注重实践 Django-Book 概述 Dingo API帮助您轻松快速地构建自己的API ...