【OpenJ_Bailian - 4117】简单的整数划分问题(dp)

版权声明:欢迎学习我的博客,希望ACM的发展越来越好~ https://blog.csdn.net/qq_41289920/article/details/89472574

题干:

将正整数n 表示成一系列正整数之和,n=n1+n2+…+nk, 其中n1>=n2>=…>=nk>=1 ,k>=1 。
正整数n 的这种表示称为正整数n 的划分。正整数n 的不同的划分个数称为正整数n 的划分数。

Input

标准的输入包含若干组测试数据。每组测试数据是一个整数N(0 < N <= 50)。

Output

对于每组测试数据,输出N的划分数。

Sample Input

5

Sample Output

7

Hint

5, 4+1, 3+2, 3+1+1, 2+2+1, 2+1+1+1, 1+1+1+1+1

解题报告:

dp[i][j]代表将i划分成最大整数为j的方案数。

AC代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<queue>
#include<map>
#include<vector>
#include<set>
#include<string>
#include<cmath>
#include<cstring>
#define F first
#define S second
#define ll long long
#define pb push_back
#define pm make_pair
using namespace std;
typedef pair<int,int> PII;
const int MAX = 55 + 5;
vector<int> vv;
ll dp[MAX][MAX];
ll ans[MAX];
int main()
{	
	int n=50;
	for(int i = 1; i<=n; i++) dp[0][i] = 1;
	for(int i = 1; i<=n; i++) {
		for(int j = 1; j<=n; j++) {
			if(i<j) dp[i][j] = dp[i][j-1];
			else dp[i][j] = dp[i-j][j] + dp[i][j-1];
		}
	}
	for(int i = 1; i<=n; i++) {
		ans[i] = dp[i][50];
	}	
	while(~scanf("%d",&n)) {
		printf("%lld\n",ans[n]);
	}
	return 0 ;
}

或者这么写也可以:

	for(int i = 1; i<=n; i++) {
		for(int j = 1; j<=n; j++) {
			if(i<j) dp[i][j] = dp[i][j-1];
			else if(i==j) dp[i][j] = dp[i][j-1]+1;
			else dp[i][j] = dp[i-j][j] + dp[i][j-1];
		}
	}

猜你喜欢

转载自blog.csdn.net/qq_41289920/article/details/89472574