问一个正整数拆分的方案有多少种,这里采用二维dp,O(n2)的时间复杂度。
dp[i][j]
=以最大划分数j划分整数i的方案。
- 我们可以很容易想到,被划分数为1时只有一种/最大划分数为1时也只有一种方案
dp[i][1] = dp[1][i] = 1;
- 如果j>i,那么仍以i为最大划分数,也就是
dp[i][j] = dp[i][i];
- 否则就是常规情况,可以以j为最大划分数/不以j为最大划分数,
dp[i][j] = dp[i-j][j] + dp[i][j-1];
由于以j为最大划分数,该方案就不用考虑j而只用考虑i-j以j为最大划分数;不以j为最大划分数则以j-1为最大划分数。
/*
* 获取以m为最大划分数划分n的方案数
* @parma n 被划分数
* @parma m 最大划分数
* @return dp[n][m] 方案数
*/
int get(int n, int m)
{
fill(dp[0], dp[0]+n*m, 0);
for (int i = 1; i <= n; ++i)
{
for (int j = 1; j <= m; ++j)
{
if (i == 1)
dp[i][j] = 1;
if (j == 1)
dp[i][j] = 1;
if (j > i)
dp[i][j] = dp[i][i];
else if (j == i)
dp[i][j] = dp[i][j-1] + 1;
else if (j < i)
dp[i][j] = dp[i-j][j] + dp[i][j-1];
}
}
return dp[n][m];
}