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