015:复杂的整数划分问题
总时间限制: 200ms 内存限制: 65536kB
描述
将正整数n 表示成一系列正整数之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 ,k>=1 。
正整数n 的这种表示称为正整数n 的划分。
输入
标准的输入包含若干组测试数据。每组测试数据是一行输入数据,包括两个整数N 和 K。
(0 < N <= 50, 0 < K <= N)
输出
对于每组测试数据,输出以下三行数据:
第一行: N划分成K个正整数之和的划分数目
第二行: N划分成若干个不同正整数之和的划分数目
第三行: N划分成若干个奇正整数之和的划分数目
样例输入
5 2
样例输出
2
3
3
提示
第一行: 4+1, 3+2,
第二行: 5,4+1,3+2
第三行: 5,1+1+3, 1+1+1+1+1+1
一些想法
动规的题典型问法就是多少种,而与具体的种类无关,本体采用记忆性递归以提高效率,根据函数参数的多少,来建立数组,如N分为K个正整数之和,就是将问题转化为在前N个数中找出K个正整数之和为N,因此是一个三维数组,递推关系则是dp[i][j][k]=dp[i-1][j][k]+dp[i][j-i][k-1](选择i,但是题目意思是可以重复使用i,因此下标还是i);而对于第二问是不同整数,则变为二维数组,dp[i][j]=dp[i-1][j]+dp[i-1][j-i](选择i,但是题目意思是可以重复使用i,因此下标还是i);第三问是奇数,则只需要加一个判断条件即可,dp[i][j]=dp[i-1][j]+dp[i][j-i](判断i是否是正奇数i%2!=0),根据递推写出递归即可,要特别注意的是,dp中的初始元素不能为0,因有的元素的值确实为0,故应小于0,如-1。
代码
#include<iostream>
#include<cstring>
using namespace std;
const int MAX = 55;
int dp1[MAX][MAX][MAX] = {
0 };
//dp[i][j][k]表示把j分成在前i个数字中选出k个之和的种数
int fun1(int i, int j, int k) {
if (j == 0 && k == 0)
return 1

本文探讨了整数划分问题的三种变化:划分成特定数量的整数之和、不同整数之和以及奇数之和。通过动态规划和记忆化递归的方法,解决了整数划分的计数问题,并提供了详细的算法实现。
最低0.47元/天 解锁文章
1万+

被折叠的 条评论
为什么被折叠?



