1. 程式人生 > >51Nod 1201 - 整數劃分(DP)

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;
}