class Solution {
  public:
    /**
     令dp[i][j]表示把数字i分成j份的方案数。
    i<j, 无解. 因为每一份至少是1.
    i==j, 1种方案。
    i>j. 先把每一份都分配上1,剩下的i-j可以分成0份dp[i-j][0],1份dp[i-j][1],2份dp[i-j][2],3份dp[i-j][3],。。。。。。j份,故有如下公式:
    dp[i][j] = 上面的k=1至j份种情况的求和;
    用d[i][j] - dp[i-1][j-1] = 和的差 = dp[i-j][j]
    得dp[i][j] = dp[i-1][j-1] + dp[i-j][j];
    实现之, 最后即为答案。
     */
    const int M = 1e9 + 7;

    int divideNumber(int n, int k) {
        if (n < k) {
            return 0;
        }

        vector< vector<int>> dp(n + 1, vector<int>(k + 1, 0));

        //k=1,dp[i][1]=1;
        for (int i = 0; i <= n; i++) {
            dp[i][1] = 1; //分成一份只能一种情况
        }

        for (int i = 0; i <= min(n, k); i++) {
            dp[i][i] = 1;
        }
        dp[0][0] = 0;

        for (int j = 1; j <= k; j++) {
            for (int i = j; i <= n; i++) { //i的数应该》=份数
                dp[i][j] = ( dp[i - 1][j - 1] + dp[i - j][j]) % M;
            }
        }

        return dp[n][k];
    }
};