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();
    }
}
posted @ 2020-10-28 10:25  童年の波鞋  阅读(106)  评论(0编辑  收藏  举报