b_51_整数划分的方案数(dp+等差数列求和公式推出限制)
将N分为若干个不同整数的和,有多少种不同的划分方式
思路:状态表示还是比较难想到的,f[i][j]表示用j个数字凑成数字i的方案数
f[i][j]+=f[i-j][j]+f[i-j][j-1],为了不重不漏
- f[i-j][j]表示用j个数凑成数字i-j,第j个数字填1的方案数(j≤i)
- f[i-j][j-1]表示用j-1个数凑成数字i-j,第j个数字填j的方案数(j≤i)
f[n][j]=1(j∈[1,m]),m的范围怎么求?数字n在组成数字为1,2,3,n等差数列的情况下数字个数最多(全1除外),假设有 n(n-1)/2≤50000,n为最大为316.2277....也就是有316个数字,m设为350即可
1+2+...+n=n(n+1)/2
1+2+...+n-1=(n-1)n/2
import java.util.*;
import java.math.*;
import java.io.*;
class Solution {
void init() {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
int n=sc.nextInt(), mod=(int)1e9+7, m=350, f[][]=new int[n+5][m+5];
for (int i=1; i<=n; i++) f[i][1]=1;
for (int i=2; i<=n; i++)
for (int j=1; j*(j+1)/2<=i; j++) {
f[i][j]=(f[i-j][j]+f[i-j][j-1])%mod;
}
int ans=0;
for (int j=1; j<m; j++)
ans=(ans+f[n][j])%mod;
System.out.println(ans);
}
}
public class Main{
public static void main(String[] args) throws IOException {
Solution s = new Solution();
s.init();
}
}