HOJ1402 整数划分

http://acm.hit.edu.cn/hoj/problem/view?id=1402

【题目描述】

整数划分是一个经典的问题。希望这道题会对你的组合数学的解题能力有所帮助。

Input

每组输入是两个整数n和k。(1 <= n <= 50, 1 <= k <= n)

Output

对于每组输入,请输出六行。

第一行: 将n划分成若干正整数之和的划分数。
第二行: 将n划分成k个正整数之和的划分数。
第三行: 将n划分成最大数不超过k的划分数。
第四行: 将n划分成若干奇正整数之和的划分数。
第五行: 将n划分成若干不同整数之和的划分数。
第六行: 打印一个空行。

Sample Input

5 2

Sample Output

7
2
3
3
3

Hint:

  1. 将5划分成若干正整数之和的划分为: 5, 4+1, 3+2, 3+1+1, 2+2+1, 2+1+1+1, 1+1+1+1+1
  2. 将5划分成2个正整数之和的划分为: 3+2, 4+1
  3. 将5划分成最大数不超过2的划分为: 1+1+1+1+1, 1+1+1+2, 1+2+2
  4. 将5划分成若干奇正整数之和的划分为: 5, 1+1+3, 1+1+1+1+1
  5. 将5划分成若干不同整数之和的划分为: 5, 1+4, 2+3

【算法分析】

  

本题相当于5个小问题,首先来看最容易做的第5个小问题:将n划分成若干不同整数之和的划分数。则是一个典型的背包装物品问题,把问题转化一下,即一个容量为n的背包,重量分别为1到n的物品各一个,求用若干物品将背包填满的方案总数。

利用动态规划的思想,很容易得到方程F[I,J] = F[I-1,J] +F[I-1,J-I],其中F[I,J]表示从前I个物品中用若干个组成的总重量为J的方案总数,转移时要保证F[I-1,J-I]有意义。答案为F[n,n],时间复杂度为O(n2)。

对于前3个小问题可以归结为一个问题,即第2个小问题:把将n划分成k个正整数之和的划分数。

为了避免重复,我们需要按照不下降的顺序进行排列。我们形象地可以把n的k份自然数划分看作n块积木堆成k列,那么不妨设这n块积木从左到右被堆成“阶梯状”。比如,下图表示的是3种10的4份自然数划分。

而将该图旋转90度,可以很容易想出一种状态表示方法。

设F[I,J,K]表示把J划分成I份最大为K的划分方案数,则有F[I,J,K] = ∑F[I-1,J-K,L],其中L = 1..K。时间复杂度为O(n2k2)。

而如果观察第一个图,我们还可以得到一种状态表示方式。设F[I,J]表示把I划分成J份的划分方案数,则有F[I,J] = ∑F[I-J,K] ,其中K = 0..J。时间复杂度为O(nk2)。

又由于F[I,J]=∑F[I-J,K](K = 0..J)=∑F[I-J,K](K = 0..J-1)+F[I-J,J] = F[I-1,J-1]+F[I-J,J],这样就把时间复杂度降为O(nk)。从另外一个角度想,我们在第一个图中“截去底边”,由于存在一个划分方案中含1的情况,我们无法确定在“截去底边”之后要把I-J分为几个数,那么不妨将划分方案中含1的情况单独列出来讨论,直接得到F[I,J] = F[I-1,J-1]+F[I-J,J]。

对于第1个小问题的答案是∑F[N,I](I = 1..N),第2个小问题的答案显然是F[N,K],而第3个小问题的答案则是∑F[N,I](I = 1..K),考虑上面旋转90度之后的图,你会发现,F[N,I]集合中的最高高度均为I,即将n划分成最大数为I的方案数。

最后来看第4个小问题,就是第2个小问题的分奇偶版本,那么设F[I,J]表示把I划分成J个奇数的划分方案数,G[I,J] 表示把I划分成J个偶数的划分方案数。那么还是用“截去底边”的思想,显然有G[I,J] = F[I-J,J]。但F[I,J]却不是直接等于G[I-J,J],因为这里又存在一个划分方案中含1的情况,同样将划分方案中含1的情况单独列出来讨论,则有F[I,J] = G[I-J,J] + F[I-1,J-1]。最后的答案就是∑F[N,I](I = 1..N),时间复杂度为O(n2)。

#include<iostream>
#include<cstdio>
#include<cstring> using namespace std; const int maxn = ; int n,k;
int f[maxn][maxn], g[maxn][maxn];
int f1[maxn][maxn], f2[maxn][maxn]; int main () {
int i, j;
int ans1, ans2, ans3, ans4, ans5;
f1[][] = ;
for (i = ; i < maxn; i ++)
for (j = ; j <= i; j ++)
f1[i][j]=f1[i-j][j]+f1[i-][j-];
f[][] = g[][] = ;
for (i = ; i < maxn; i ++)
for (j = ; j <= i; j ++){
g[i][j] = f[i - j][j];
f[i][j] = f[i - ][j - ] + g[i - j][j];
}
for (i = ; i < maxn; i ++)
f2[i][] = ;
for (i = ; i < maxn; i ++)
for (j = ; j < maxn; j ++){
f2[i][j] = f2[i - ][j];
if (j - i >= )
f2[i][j] += f2[i - ][j - i];
} while (scanf ("%d %d", &n, &k) != EOF){
ans1 = ans2 = ans3 = ans4 = ans5 = ;
for (i = ; i <= n; i ++)
ans1 += f1[n][i];
ans2 = f1[n][k];
for (i = ; i <= k; i ++)
ans3 += f1[n][i];
for (i = ; i <= n; i ++)
ans4 += f[n][i];
ans5 = f2[n][n];
printf ("%d\n%d\n%d\n%d\n%d\n\n", ans1, ans2, ans3, ans4, ans5);
}
return ;
}

HOJ 1402 整数划分的更多相关文章

  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. Asp.Net Core App 部署故障示例 2

    相关阅读:Windows + IIS 环境部署Asp.Net Core App 1.  HTTP Error 502.5 – Process Failure 环境 Windows Server 201 ...

  2. 【BZOJ】【2286】【SDOI2011】消耗战

    虚树+树形DP Orz ZYF……果然好神…… 建虚树先按dfn排序,再用一个单调栈来维护当前这条[链],往里加边……说实话还没弄懂- - 留个坑吧…… RE的原因:这条链往出退的时候没写top--; ...

  3. iOS:UIToolBar控件的使用

    UIToolBar控件:是经常使用的一个工具条控件,虽然在上面可以添加子控件,但是toolbar中只能添加UIBarButtonItem类型的子控件,其他子控件会被包装成这种类型的,例如UIButto ...

  4. LZO 使用和介绍

    LZO说明 摘要 LZO 是一个用 ANSI C 语言编写的无损压缩库.他能够提供非常快速的压缩和解压功能.解压并不需要内存的支持.即使使用非常大的压缩比例进行缓慢压缩出的数据,依然能够非常快速的解压 ...

  5. 第十章 Redis持久化--RDB+AOF

    注:本文主要参考自<Redis设计与实现> 1.Redis两种持久化方式 RDB 执行机制:快照,直接将databases中的key-value的二进制形式存储在了rdb文件中 优点:性能 ...

  6. jquery圆角插件

    为了实现div的圆角效果,你还在用古老的背景图片拼凑的方法吗?还是在用各种浏览器不互相兼容的CSS方式?如果你还在用这样的方式实现圆角,那我告诉你你真的out了,或许是我out了,竟然以前没发现有这样 ...

  7. 根据百度API获得经纬度,然后根据经纬度在获得城市信息

    package com.pb.baiduapi; import java.io.BufferedReader; import java.io.IOException; import java.io.I ...

  8. 使用Gnupg对Linux系统中的文件进行加密

    GnuPG(GNU Privacy Guard或GPG)是一个以GNU通用公共许可证释出的开放源码用于加密或签名的软件,可用来取代PGP.大多数gpg软件仅支持命令行方式,一般人较难掌握.由于gpg软 ...

  9. Idea代码可视化插件

    Idea代码可视化插件 https://plugins.jetbrains.com/plugin/7324-code-iris

  10. FM遇到错误RQP-DEF-0354和QE-DEF-0144

    版本:Cognos 10.2.1 系统:Win10 操作过程:在FM调用了一个存储过程,其中引用了前端page页面的参数如下图所示,在验证和保存查询主题的时候一直提示参数没有替换值,错误 信息如下图所 ...