整数划分——经典dp
来源:互联网 发布:用c语言打开文件 编辑:程序博客网 时间:2024/06/05 10:40
题目:
给两个整数n和k,分别计算一下情况的数目。(1 <= n <= 50, 1 <= k <= n)
1、将n划分成若干正整数之和的划分数。
2、将n划分成k个正整数之和的划分数。
3、将n划分成最大数不超过k的划分数。
4、将n划分成若干个奇正整数之和的划分数。
5、将n划分成若干不同整数之和的划分数。
一、将n划分成若干正整数之和的划分数。
这种情况没说划分的整数不能相同,例如5 = 2+2+1,可以划分出两个2来。
用dp[i][j]表示将i划分为最大数不超过j的划分数:
1、当i<j时,因为j不可能大于i,所以dp[i][j] = dp[i][i]。
2、当i>j时,根据划分中有没有j分为两种情况:如果有j那么dp[i][j] = dp[i-j][j],即去掉这个j剩余其他数的划分;如果没有j,那么 dp[i][j] = dp[i][j-1],即i划分为不超过j-1的划分数。综合dp[i][j] = dp[i-j][j] +dp[i][j-1]。
3、当i=j时,还是根据划分中有没有j分为两种情况:如果有j,那么只有1中划分;如果没有j,dp[i][j] = dp[i][j-1]。综合dp[i][j] = 1+dp[i][j-1]。
最后dp[n][n]表示将n划分成不超过n的划分数,即结果。
二、将n划分成k个正整数之和的划分数。
用dp[i][j]表示将i划分为j个整数的划分数:
1、当i<j时,不可能存在,所以dp[i][j] = 0。
2、当i>j时,根据划分的数数有没有1这个数字分为两种情况:如果含有1,那么dp[i][j] = dp[i-1][j-1],即把这个1拿出来,将剩下的i-1划分为j-1份;如果不含有1,那么dp[i][j] = dp[i-j][j],即从每一份中拿出一个1,总数就变成了i-j但划分数目不变。综合为:dp[i][j] = dp[i-1][j-1] + dp[i-j][j]。
最后dp[n][k]就是结果。
3、当i=j时,这时只有一种划分,即每份都是1,dp[i][j] = 1。
三、将n划分成最大数不超过k的划分数。
这种情况与第一种情况的解法相同,dp[n][k]就是最后结果。
四、将n划分成若干个奇正整数之和的划分数。
用p[i][j]表示将i划分为j个奇数的划分数,用q[i][j]表示将i划分为j个偶数的划分数。
1、偶数的划分数可以由奇数来或得,即划分后的每个偶数都减去1,就变成了奇数,所以q[i][j] = p[i-j][j]
2、奇数的划分根据有没有1分为两种情况:如果含有1,那么p[i][j] = p[i-1][j-1],即拿去这个1,将剩下的i-1划分为j-1份;如果不含有1,那么每份都减去1,就变成了偶数,p[i][j] = q[i-j][j]。综合p[i][j] = p[i-1][j-1] + q[i-j][j]。
最后结果为:p[n][0]+p[n][1]+……+p[n][n]。
五、将n划分成若干不同整数之和的划分数。
与第一种情况有些相似,但是划分中不能有相同的数。(下面红色标记是与第一种情况的不同之处)
用dp[i][j]表示将i划分为不超过j的不同数的划分数:
1、当i<j时,因为j不可能大于i,所以dp[i][j] = dp[i][i]。
2、当i>j时,根据划分中有没有j分为两种情况:如果有j那么dp[i][j] = dp[i-j][j-1],即去掉这个j剩余其他数的划分,其余划分中最大数为j-1;如果没有j,那么 dp[i][j] = dp[i][j-1],即i划分为不超过j-1的划分数。综合dp[i][j] = dp[i-j][j-1] +dp[i][j-1]。
3、当i=j时,还是根据划分中有没有j分为两种情况:如果有j,那么只有1中划分;如果没有j,dp[i][j] = dp[i][j-1]。综合dp[i][j] = 1+dp[i][j-1]。
最后dp[n][n]就是结果。
这种情况还可以用另一种方法,类似于第二种情况:
用dp[i][j]表示为将i划分为j个不同的数,1、当i<j时,不可能存在,dp[i][j] = 0。
2、当i=j时,由于划分的数都不能相同,所以也不存在,dp[i][j] = 0。
3、当i>j时,根据有没有1分为两种情况:如果含有1,那么每份都去掉1后就是将i-j划分为j-1个不同的数,dp[i][j]=dp[i-j][j-1];如果不含有1,那么每份都去掉1后就是将i-j划分为j个不同的数,dp[i][j] = dp[i-j][j]。综合dp[i][j] = dp[i-j][j-1]+dp[i-j][j]。
最后结果为dp[n][1]+dp[n][2]+……+dp[n][n]。
以上仅仅是思路,没有代码。如果有错误,请帮忙指出,谢谢。
- 整数划分——经典dp
- DP经典 ----- 整数划分
- 区间dp—整数划分
- hoj 整数划分问题 经典dp
- NYOJ90 整数划分(经典递归和dp)
- dp整数划分问题——03:复杂的整数划分问题
- nyist 746 整数划分(四)(经典DP)
- 百练:简单的整数划分问题(经典dp)
- 哈理工OJ 2004 整数划分(经典dp问题)
- 区间DP——整数划分(使乘积最大)
- 【划分型DP】整数划分
- 区间DP 整数划分
- 整数划分问题 【DP】
- 整数划分问题 DP
- 整数划分 区间dp
- 整数划分(区间dp)
- 整数划分DP
- dp-整数划分问题
- Qt常用部件介绍
- switch用法
- 绳子与重物
- HtttpClient的相关实例
- mysql show status查看数据库状态
- 整数划分——经典dp
- 忽略SIGCHLD信号来避免僵尸进程
- 解决:Cannot push these commits as they contain an email address marked as private on GitHub
- 两个栈实现一个队列
- SPSS学习笔记(一)
- The Log
- Android中尺寸单位介绍
- C/C++通过WMI和系统API函数获取获取系统硬件(cpu,内存,显卡,网卡)配置信息
- 推荐10款很酷的编辑器 开发人必备!