4117:简单的整数划分问题
http://bailian.openjudge.cn/practice/4117
4119:复杂的整数划分问题
http://bailian.openjudge.cn/practice/4119

# 把正整数N划分成 K个正整数 之和的划分数目 0 < K <= N
def NK_dp(n, k):dp = [[0 for i in range(n + 1)] for j in range(n + 1)]dp[0][0] = 1  # 第1行 = 1for i in range(1, n + 1):  # 遍历第[1,n]行for j in range(0, i + 1):  # 遍历第[0,i]列if j == 1:  # 第1行 = 1dp[i][j] = 1else:  # 左上 + 上dp[i][j] = dp[i - 1][j - 1] + dp[i - j][j]return dp[n][k]# 把正整数N划分成 K个正整数 之和的划分数目 0 < K <= N
def NK_recur(n, k):# NK_recur(0, 0) = 1 为什么??????????if n == k or k == 1:# 当n == k时,N划分成 K个1# 当k == 1时,N划分成 1个Nreturn 1  # 对角线和第1行 = 1elif n < 1 or k < 1 or n < k:return 0  # 第0行,第0列,对角线右上方 = 0else:  # 左上 + 上# 把正整数i划分成 j个正整数(不存在1) 之和的划分数目 =# 把正整数(i-j)划分成 j个正整数 之和的划分数目 NK_recur[i-j][j] 每个整数都同时减1# 把正整数i划分成 j个正整数(存在1) 之和的划分数目 =# 把正整数(i-1)划分成 (j-1)个正整数 之和的划分数目 NK_recur[i-1][j-1] 去掉里面的1return NK_recur(n - 1, k - 1) + NK_recur(n - k, k)# 把正整数n划分成 n<m的 若干个 不同正整数 之和的划分数目
# N划分成 若干个不同正整数 之和的划分数目
def Ndiff_dp(n):dp = [[0 for i in range(n + 1)] for j in range(n + 1)]dp[0][0] = 1  # 除了[0][0]是1之外,第0列都是0for i in range(n + 1):  # 遍历第[0,n]行for j in range(1, n + 1):  # 遍历第[1,n]列if i < j:dp[i][j] = dp[i][i]else:dp[i][j] = dp[i][j - 1] + dp[i - j][j - 1]return dp[n][n]# 把正整数n划分成 n<m的 若干个 不同正整数 之和的划分数目
def Ndiff_recur(n, m):if (n == 0):  #return 1  # 第0行 为什么是1???elif (m < 1):  # 因为 m < 1 不是正整数,所以返回0return 0  # 除了[0][0]是1之外,第0列都是0elif (n < m):return Ndiff_recur(n, n)  # 左elif (n == m):# 当划分包含 m 时, m = m ,只有一种划分方法;# 当 不包含 m 时, 有 func(n, m - 1) 种划分方法。return Ndiff_recur(n, m - 1) + 1  # 左 + 1elif (n > m):  # 上左 + 左# (1)划分中包含 m 时,有func(n - m, m - 1)种划分方法# (2)划分中不包含 m 时,有func(n, m - 1)种划分方法return Ndiff_recur(n - m, m - 1) + Ndiff_recur(n, m - 1)# 把正整数n划分成 n<m的 若干个 可相同的正整数 之和的划分数目
def Nsame_recur(n, m):if (n == 1 or m == 1):# (1)当 n == 1 时,无论 m 取何值,都只能 划分为 1;# (2)当 m == 1 时 ,无论 n 为何值, 也只能划分为 n 个 1 相加 ,只有一种划分方法;return 1elif (n < m):return Nsame_recur(n, n)  # 左elif (n == m):# 当划分包含 m 时, m = m ,只有一种划分方法;# 当 不包含 m 时, 有 func(n, m-1) 种划分方法。return Nsame_recur(n, m - 1) + 1  # 左 + 1elif (n > m):# (1)划分中包含 m 时, 有func(n -m, m) 种划分方法;# (2)划分中不包含 m 时, 有 func(n, m-1)种划分方法;return Nsame_recur(n - m, m) + Nsame_recur(n, m - 1)  # 上 + 左# 把整数 n 划分为 <= n 的一系列数字之和 的划分方法种数
def Nsame_dp(n):f = [[0 for t in range(n + 1)] for i in range(n + 1)]for i in range(1, n + 1):  # 从左到右遍历列[1,n]f[i][1] = 1  # 第1列 = 1for m in range(2, n + 1):  # 从左到右遍历列[2,n]f[1][m] = 1  # 第1行 = 1for i in range(2, n + 1):  # 从上到下遍历行[2,n]if (i < m):  # n < m 在对角线上方f[i][m] = f[i][i]elif (i == m):f[i][m] = f[i][m - 1] + 1else:  # n >= m 在对角线上或其下方f[i][m] = f[i - m][m] + f[i][m - 1]return f[n][n]def DivideInt_dp(N, K):  # 动态规划dp1 = [[0 for i in range(N + 1)] for j in range(N + 1)]dp2 = [[0 for i in range(N + 1)] for j in range(N + 1)]dp3 = [[0 for i in range(N + 1)] for j in range(N + 1)]# dp[n][k] 把正整数n划分成 k个正整数 之和的划分数目 0 < K <= N# dp[n][m] 把正整数n划分成 n<m的 若干个 不同正整数 之和的划分数目# dp[n][m] 把正整数n划分成 n<m的 若干个 可相同的正整数 之和的划分数目for i in range(1, N + 1):for j in range(1, N + 1):if (i < j):dp1[i][j] = 0dp2[i][j] = dp2[i][i]dp3[i][j] = dp3[i][i]elif (i == j):dp1[i][j] = 1dp2[i][j] = dp2[i][j - 1] + 1dp3[i][j] = dp3[i][j - 1] + 1else:# dp[n][k] = dp[n - k][k] + dp[n - 1][k - 1]dp1[i][j] = dp1[i - j][j] + dp1[i - 1][j - 1]# dp[n][m] = dp[n][m - 1] + dp[n - m][m - 1]dp2[i][j] = dp2[i][j - 1] + dp2[i - j][j - 1]# dp[n][m] = dp[n][m - 1] + dp[n - m][m]dp3[i][j] = dp3[i][j - 1] + dp3[i - j][j]# dp1[N][K] 把正整数N划分成 K个正整数 之和的划分数目 0 < K <= N# dp2[N][N] 把正整数N划分成 若干个 不同正整数 之和的划分数目# dp3[N][N] 把正整数N划分成 若干个 可相同的正整数 之和的划分数目return dp1[N][K], dp2[N][N], dp3[N][N]def DivideOddInt_dp(N):f = [[0 for i in range(N + 1)] for j in range(N + 1)]  # N划分成K个奇正整数之和的划分数目g = [[0 for i in range(N + 1)] for j in range(N + 1)]  # N划分成K个偶正整数之和的划分数目# 把i-j划分成j个正奇数 → 把j个正奇数分别+1 → 把i划分成j个正偶数,即 f[i-j][j] = g[i][j]# 把i-j划分成j个正偶数 → 把j个正偶数分别+1 → 把i划分成j个正奇数,即 g[i-j][j] = f[i][j]f[0][0] = 1g[0][0] = 1for i in range(1, N + 1):  # 遍历第[1,N]行for j in range(1, i + 1):  # 遍历第[1,i]列g[i][j] = f[i - j][j]  # 上# 划分中不包含1:划分中每个数都>1,那么每个数都-1变成j个正偶数# 问题变为 把i-j划分成j个正偶数 g[i-j][j]# 划分中包含1:把这个1去掉,问题变为 把i-1划分成j-1个正奇数 f[i-1][j-1]f[i][j] = f[i - 1][j - 1] + g[i - j][j]  # 上左 + 上return f, g# 把正整数N划分成 若干个 奇正整数 之和的划分数目
def Nodd_dp(n):dp = [[0 for i in range(n + 1)] for j in range(n + 1)]for i in range(0, n + 1):dp[i][1] = 1if (i % 2) == 1:dp[0][i] = 1  # 预处理第0层for i in range(1, n + 1):for j in range(1, n + 1):if (j % 2) == 1:if (j <= i):dp[i][j] = dp[i - j][j] + dp[i][j - 1]else:dp[i][j] = dp[i][i]else:dp[i][j] = dp[i][j - 1]  # 当前非奇数return dp[n][n]# https://blog.csdn.net/tp7309/article/details/54880495
while True:try:line = input().split()except EOFError:breakN = int(line[0])K = int(line[1])# dp1[N][K] 把正整数N划分成 K个正整数 之和的划分数目 0 < K <= N# dp2[N][N] 把正整数N划分成 若干个 不同正整数 之和的划分数目# dp3[N][N] 把正整数N划分成 若干个 可相同的正整数 之和的划分数目ans1, ans2, ans3 = DivideInt_dp(N, K)# 把正整数N划分成K个奇正整数之和的划分数目# 把正整数N划分成K个偶正整数之和的划分数目ff, gg = DivideOddInt_dp(N)# dp1[N][K] 把正整数N划分成 K个正整数 之和的划分数目 0 < K <= Nprint(ans1)print(NK_recur(N, K))print(NK_dp(N, K))print()# dp2[N][N] 把正整数N划分成 若干个 不同正整数 之和的划分数目print(ans2)print(Ndiff_recur(N, N))print(Ndiff_dp(N))print()# dp3[N][N] 把正整数N划分成 若干个 可相同的正整数 之和的划分数目print(ans3)print(Nsame_recur(N, N))print(Nsame_dp(N))print()# 把正整数N划分成 若干个 奇正整数 之和的划分数目sumsum = 0  # 对第N行求和for i in range(0, N + 1):sumsum += ff[N][i]print(sumsum)print(Nodd_dp(N))

整数划分问题 递归 动态规划 openjudge 百练 python相关推荐

  1. 贪心算法 openjudge 百练 python

    https://www.icourse163.org/learn/PKU-1001894005?tid=1450413466#/learn/content 程序设计与算法(二)算法基础 这里写目录标题 ...

  2. 58 - 算法 -分治问题 - 循环 二分查找 OpenJudge 百练 4143和为给定数

    #define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstdio> #include <cmath ...

  3. [OpenJudge] 百练2754 八皇后

    八皇后 Description 会下国际象棋的人都很清楚:皇后可以在横.竖.斜线上不限步数地吃掉其他棋子.如何将8个皇后放在棋盘上(有8 * 8个方格),使它们谁也不能被吃掉!这就是著名的八皇后问题. ...

  4. 【拓扑排序专题】Openjudge百练 4084 拓扑排序

    http://bailian.openjudge.cn/practice/4084/ 4084:拓扑排序 描述 给出一个图的结构,输出其拓扑排序序列,要求在同等条件下,编号小的顶点在前. 输入 若干行 ...

  5. (C语言)整数划分问题 递归和递推

    题目内容: 对于一个正整数n的划分,就是把n变成一系列正整数之和的表达式.注意,分划与顺序无关,例如6=5+1跟6=1+5是 同一种分划.另外,单独这个整数本身也算一种分划. 例如:对于正整数n=5, ...

  6. Python入门习题(63)——OpenJudge百练习题:DNA排序

    OpenJudge百练第1007号习题:DNA排序 题目描述 解题思路 参考答案 测试用例 小结 题目描述 来源 OpenJudge网站 – 百练习题集-第1007号习题 建议学编程的人士利用好这个网 ...

  7. Python入门习题(73)——OpenJudge百练习题:买手机

    OpenJudge百练第4069号习题:买手机 题目描述 解题思路 参考答案 测试用例 小结 题目描述 来源 OpenJudge网站 – 百练习题集-第4069号习题 要求 总时间限制: 1000ms ...

  8. Python入门习题(69)——OpenJudge百练习题:买房子

    OpenJudge百练第4022号习题:买房子 题目描述 解题思路 参考答案 测试用例 小结 题目描述 来源 OpenJudge网站 – 百练习题集-第4022号习题 要求 总时间限制: 1000ms ...

  9. Python入门习题(82)——OpenJudge百练习题:第二大价值

    OpenJudge百练第4098号习题:第二大价值 题目描述 解题思路 参考答案 测试用例 小结 题目描述 来源 OpenJudge网站 -- 百练习题集-第4098号习题 要求 总时间限制: 300 ...

最新文章

  1. Laravel核心解读--完结篇
  2. 利用 CSS selector 改变悬停表格样式
  3. R语言实战应用精讲50篇(七)-因子
  4. Kubernetes客户端client-go简介
  5. Mail group(转至毅冰)
  6. 计算机网络 | 网络基础 :网络协议,协议分层,数据封装与分用,地址管理,字节序
  7. VMware虚拟机扩展Ubuntu系统磁盘空间
  8. 2018.08.09洛谷P3959 宝藏(随机化贪心)
  9. 页面分栏LayoutInflater
  10. Flex 3 metadata tags 标签
  11. Flink : UnknownTaskExecutorException: No TaskExecutor registered under
  12. 机器学习算法总结之Boosting:AdaBoost
  13. 不能不说的C#特性-表达式树
  14. 【活动报名】1024,一起过节,一起品网易/美团/贝壳/PingCAP/爱奇艺云原生实践干货!
  15. 移动ESP分区到磁盘最前端
  16. idea顶部工具栏、底部工具栏、两边工具栏的显示与隐藏
  17. Belief System
  18. 【Java例题】3.6 计算arcsin(x)的值
  19. 听说你刚中了NIPS?恭喜(研究德扑、老鼠胡须等AI的都入围了)
  20. The Pursuit of Happyness 当幸福来敲门(励志电影推荐)

热门文章

  1. WordPress建站教程 从零开始服务器搭建网站超详细
  2. 基于人工智能视觉芯的高速公路交通事故预警预测方案
  3. 谈谈内卷、IT行业怎么避免内卷?
  4. java计算机毕业设计视频点播系统源码+系统+数据库+lw文档+mybatis+运行部署
  5. esp32c3 问题解决
  6. 最全的linux基础学习视频
  7. 推荐系统遇上深度学习(二十一)--贝叶斯个性化排序(BPR)算法原理及实战
  8. Windows必备:五款靠谱好用的软件,简洁纯净无广告
  9. 华为时间管理之仁者见仁
  10. 什么样内容的书值得买纸质书