51Nod 1201 - 整数划分(DP)

【题目描述】
在这里插入图片描述

【思路】
d p [ i ] [ j ] i j dp[i][j] 表示数字i被划分成j个互不相同的数字之和的方案数,那么 d p [ i ] [ j ] = d p [ i j ] [ j ] + d p [ i 1 ] [ j 1 ] dp[i][j]=dp[i-j][j]+dp[i-1][j-1] i j j + 1 i i j j 1 + 1 1 i j j ( j 1 ) / 2 j 2 j n 前一项表示数字i-j被划分成j个互不相同的数,然后每个数字+1就能得到数字i了,后一项表示数字i-j被划分成j-1个互不相同的数,然后每个数字+1后再加上一个数字1也能得到数字i,j个互不相同的数相加至少是j(j-1)/2,是j^2的级别,所以j只需要枚举到\sqrt{n}的数量级就可以了

#include<bits/stdc++.h>
using namespace std;

const int mod=1e9+7;
const int maxn=50005;
const int maxm=505;

int n;
int dp[maxn][maxm];

int main(){
	scanf("%d",&n);
	dp[0][0]=1;
	for(int i=1;i<=n;++i){
		for(int j=1;j<maxm;++j){
			if(i>=j) dp[i][j]=((long long)dp[i-j][j]+dp[i-j][j-1])%mod;
		}
	}
	long long ans=0;
	for(int j=1;j<maxm;++j){
		ans=(ans+dp[n][j])%mod;
	}
	printf("%lld\n",ans);
	return 0;
}

猜你喜欢

转载自blog.csdn.net/xiao_k666/article/details/83757162
今日推荐