#include <bits/stdc++.h>
using namespace std;
int slvK(int n,int k){
auto dp=vector<vector<int>>(n+1,vector<int>(n+1,0));
//dp[i][j]:将整数i划分为j个整数之和的划分数
dp[0][0]=1;
for(int i=1;i<=n;++i){
for(int j=1;j<=i;++j){
dp[i][j]=dp[i-j][j]+dp[i-1][j-1];
//dp[i-j][j]:i的划分中不包含1
//dp[i-1][j-1]:划分包含1
}
}
return dp[n][k];
}
int slvD(int n){
auto dp=vector<vector<int>>(n+1,vector<int>(n+1,0));
//dp[i][j]:将整数i划分为最大数为j的划分数
dp[0]=vector<int>(n+1,1);
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(j>i) dp[i][j]=dp[i][i];
else dp[i][j]=dp[i-j][j-1]+dp[i][j-1];
//dp[i-j][j-1]:i里包含j
//dp[i][j-1]:不包含j
}
}
return dp[n][n];
}
int slvO(int n)
{
auto dp=vector<vector<int>>(n+1,vector<int>(n+1,0));
//dp[i][j]:将整数i划分为最大数为j的划分数
for(int i=1;i<=n;++i){
dp[i][1]=dp[0][i]=1;
}
for(int i=1;i<=n;++i){
for(int j=1;j<=n;++j){
if(j%2){//j为奇数
if(j>i) dp[i][j]=dp[i][i];
else dp[i][j]=dp[i-j][j]+dp[i][j-1];
}
else dp[i][j]=dp[i][j-1];
}
}
return dp[n][n];
}
int main()
{
int n,k;
while(~scanf("%d %d",&n,&k)){
printf("%d\n",slvK(n,k));
printf("%d\n",slvD(n));
printf("%d\n",slvO(n));
}
return 0;
}
4119:复杂的整数划分问题
最新推荐文章于 2022-12-10 20:07:55 发布
本文介绍了一种用于解决整数划分问题的算法实现,包括求解特定整数k个数的划分方式、最大数为整数本身的划分方式以及仅考虑奇数作为划分元素的情况。通过动态规划方法高效解决了这三类整数划分问题。

2906

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



