版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/m0_37286282/article/details/79719768
之前写过类似的文章,今天看到另外一种划分数的方法,也就是将n划分成不大于m的种数。
若是划分多个整数可以存在相同的:
dp[n][m]= dp[n][m-1]+ dp[n-m][m] dp[n][m]表示整数 n 的划分中,每个数不大于 m 的划分数。 则划分数可以分为两种情况: a.划分中每个数都小于 m,相当于每个数不大于 m- 1, 故划分数为 dp[n][m-1]. b.划分中有一个数为 m. 那就在 n中减去 m ,剩下的就相当于把 n-m 进行划分, 故划分数为 dp[n-m][m];
若是划分多个不同的整数:
dp[n][m]= dp[n][m-1]+ dp[n-m][m-1] dp[n][m]表示整数 n 的划分中,每个数不大于 m 的划分数。 同样划分情况分为两种情况: a.划分中每个数都小于m,相当于每个数不大于 m-1,划分数为 dp[n][m-1]. b.划分中有一个数为 m.在n中减去m,剩下相当对n-m进行划分, 并且每一个数不大于m-1,故划分数为 dp[n-m][m-1]。
#include <iostream>
using namespace std;
int getNum( int n, int m )
{
if( 1 == n || 1 == m )
return 1;
if( n <= m )
return getNum( n, n - 1 ) + 1;
else
return getNum( n, m - 1 ) + getNum( n - m, m );
}
void main()
{
int n, m;
cin >> n >> m;
cout << getNum( n, m ) << endl;
}
例题:来源计蒜客
划分数就是将整数 nn 分成若干个大于 00 的数的和。例如,n = 4n=4,可以分成 1+1+1+11+1+1+1,1+1+21+1+2,1+31+3,2+22+2,44,一共 55 种方案,注意 1+1+21+1+2,1+2+11+2+1,2+1+12+1+1 被认为是相同的方案。
求整数 8080 的划分数方案。
dfs就不贴代码了,用了一种dp,dp[n][k]表示数n取分成k份,dp[n][k]=dp[n-1][k-1]+dp[n-k][k]分为有1和没有1.
#include<bits/stdc++.h>
using namespace std;
int dp[100][100];
int main()
{
int n;
cin>>n;
dp[0][0]=1;
for(int i=1;i<=n;i++)
dp[i][0]=0;
for(int i=1;i<n;i++)
{
for(int j=i+1;j<=n;j++)
{
dp[i][j]=0;
}
}
for(int i=1;i<=n;i++)
{
for(int j=1;j<=i;j++)
{
dp[i][j]=dp[i-1][j-1]+dp[i-j][j];
}
}
long long ans=0;
for(int i=1;i<=n;i++)
{
ans+=dp[n][i];
}
cout<<ans<<endl;
return 0;
}