题目描述
要把m升的水倒入n个相同的容器中(假设容器足够大),允许有的容量是空的,
问共有多少种不同的倒法?5,1,1和1,5,1和1,1,5是同一种倒法。
示例
输入:
7 3
输出:
8
参考解析
1. 不妨设 f(m,n)为 把m升水倒入n个容器的总的方法数。
2. m>=n 可以分为两种情况,一种是n个容器内都一定有水,一种是n个容器内至少有一个没有水,这两种情况完全独立。
对于第一种,我们先将m中分出n升水,依次倒入每个桶,这样每个桶都一定有水,那么接下来的水的分配就是f(m-n,n)。
对于第二种的想法,就是先丢掉一个桶,这个桶一定没水,然后将m升水分配给余下的n-1个桶里(每个桶也不一定有水)。
所以有dp[ i ][ j ] = dp[ i ][ j -1 ] + dp[ i - j ][ j ] 。
3. 下面是m<n的情况,也就是水少桶多,那么桶太多必定有部分桶未装水的情况。所以不妨直接扔掉(n-m)个桶,
然后就变成了n升水分配给n个桶的情况,即 dp[i][j] = dp[i][j-1];
4. 接下来初始化边值条件:dp[ 0 ][ i ] = 1, dp[ j ][ 0 ] = 1.在我的代码中,索引下标和水量,以及桶数都是一一对应的。
参考代码
public static int solve(int m, int n) {
int dp[][] = new int[m+1][n+1];
for (int i = 0; i < m+1; i++) {
Arrays.fill(dp[i], 1);
}
for (int i = 2; i < m+1; i++) {
for (int j = 2; j < n+1; j++) {
if (i >= j)
dp[i][j] = dp[i][j - 1] + dp[i - j][j];
else
dp[i][j] = dp[i][j - 1];
}
}
return dp[m][n];
}