小红书-放水果

文章讲述了如何使用动态规划方法解决将M个相同的水果放入N个盘子的问题,通过初始化和递推计算不同放法数,重点在于理解dp[i][j]的含义和递推公式。
摘要由CSDN通过智能技术生成

题目:

放水果
把M个相同的水果放在N个同样的盘子里,允许有的盘子空着不放,问不同的放法数K是多少?请注意,511151 是同一种放法。

输入描述
第一行是测试数据的数目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]
}

有大佬路过可以给点帮助

  • 6
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值