递归&动态规划 - 不严格递减子序列的数量 牛客网HJ61 放苹果

描述

把m个同样的苹果放在n个同样的盘子里,允许有的盘子空着不放,问共有多少种不同的分法?
注意:如果有7个苹果和3个盘子,(5,1,1)和(1,5,1)被视为是同一种分法。

数据范围:0≤m≤10 0≤m≤10 ,1≤n≤10 1≤n≤10 。

输入描述:
输入两个int整数
输出描述:
输出结果,int型

示例1
输入:
7 3
输出:
8

理解

注意苹果和盘子均是无序的,因此将求解该问题理解为求解满足下列条件的数列数量:
① 长度为n(盘子数)
② 和为m(苹果数)
③ 不严格递减(无序性)

求解该问题,有两种思路:

方案1:递归

固定数组第一项的数,求剩余部分满足条件的数列的数量,代码:

# 苹果和盘都是无序的
# 不递增数列的数量
def getNonIncreaseListNum(head_cap,sum,size):
    if(sum < 0): return 0
    if(head_cap*size<sum): return 0
    if(sum == 0): return 1
    if(size == 1): return 1
    list_num = 0
    for head_fig in range(head_cap,-1,-1):
        list_num += getNonIncreaseListNum(head_fig,sum-head_fig,size-1)
    return list_num
    
input_str = input()
m,n = list(map(int,input_str.split()))
way_num = getNonIncreaseListNum(m,m,n)
print(way_num)

方案2:动态规划

假设数列和为i,数列长度为j,满足条件的数列数量为dp[i][j],那么,
当i<j时,由于数列递增,那么必定数列的后(j-i)项为0,因此
当i<j,dp[i][j] = dp[i][i]
否则当i≥j时,有两种情况:数列最后一项是否为0。
当数列最后一项为0时,此时满足条件的数列数量为:dp[i][j-1]
当数列最后一项不为0时,若将数列每一项减1,等价于满足数列和为i-j的数列和数量,因此
当i≥j时,dp[i][j] = dp[i][j-1] + dp[i-j][j]
特别的,dp[0][j]=1,dp[1][j] = 1,dp[i][1] = 1
代码:

# 苹果和盘都是无序的
# 不递增数列的数量

input_str = input()
m,n = list(map(int,input_str.split()))
dp = [[1]*(n+1)]
dp.append([1]*(n+1))

for i in range(2,m+1):
    dp.append([1]*(n+1))
    for j in range(2,n+1):
        if(i<j):
            dp[i][j] = dp[i][i]
        else:
            dp[i][j] = dp[i-j][j] + dp[i][j-1]
print(dp[m][n])
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值