将n划分成最大数不超过m的划分数

版权声明:本文为博主原创文章,未经博主允许不得转载。 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+11+1+21+1+21+31+32+22+244,一共 55 种方案,注意 1+1+21+1+21+2+11+2+12+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;
}



猜你喜欢

转载自blog.csdn.net/m0_37286282/article/details/79719768