题目:
放水果
把M个相同的水果放在N个同样的盘子里,允许有的盘子空着不放,问不同的放法数K是多少?请注意,5,1,1和1,5,1 是同一种放法。
输入描述
第一行是测试数据的数目t(0 <= t <= 20),随后的每行均包含二个整数M和N,以空格分开。1<=M,N<=10。
输出描述
对输入的每组数据M和N,在单独的行里输出相应的K。
样例输入
5
2 5
3 3
9 5
2 10
5 1
样例输出
2
3
23
2
1
面试官给了提示:
dp[i][j]表示将i个水果放入j个盘子的放法数。我们首先初始化所有dp[i][0]为1,因为将任何数量的水果放入0个盘子只有一种方法,即不放。然后,我们逐行填充动态规划表,对于每个dp[i][j],如果j大于i,则dp[i][j]等于dp[i][i],因为多余的盘子无法放入水果;否则,dp[i][j]等于dp[i][j-1](不使用第j个盘子的放法数)加上dp[i-j][j](使用第j个盘子的放法数)。最后,dp[n][m]就是我们要求的结果。
需要考虑两种情况:一种是不使用第j个盘子,另一种是使用第j个盘子。dp[i][j-1]表示的是第一种情况的放法数,dp[i-j][j]表示的是第二种情况的放法数。将这两种情况的放法数相加,就得到了总的放法数。
当时是没看懂的,主要也不太懂为啥dp[i-j][j]表示的是第二种情况的放法数
按照提示写了代码,但是运行结果也不对
package main
import "fmt"
import "io"
// To execute Go code, please declare a func main() in a package "main"
// The TestCase is shown below
// Input : 1 2
// Output : 3
func main() {
var t int
_,err := fmt.Scanf("%d", &t)
if err != nil {
fmt.Println("err")
return
}
for i := 0; i < t; i ++ {
var M ,N int
_,err := fmt.Scanf("%d %d", &M, &N)
if err == io.EOF {
break
}else{
// fmt.Println(M, N)
fmt.Println(test(M, N))
// fmt.Println("Your result is : ", a + b)
}
}
}
func test(M, N int) int {
dp := make([][]int, M+1)
for i := 0; i <= M; i ++ {
dp[i] = make([]int, N+1)
dp[i][0] = 1
}
for i := 0; i <= M; i ++ {
for j := 1; j <= N; j ++ {
if j > i {
dp[i][j] = dp[i][i]
} else {
dp[i][j] = dp[i-j][j] + dp[i][j-1]
}
}
}
return dp[M][N]
}
有大佬路过可以给点帮助