洛谷 python P1077 [NOIP2012 普及组] 摆花

本文介绍了花盆问题与背包问题的区别,阐述了解决花盆问题的动态规划方法,重点在于状态转移的计算和优化思路的应用,以及给出了相应的Python代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

继续骂:煞笔洛谷、煞笔出题人
又是这种不清不楚、容易误导解题思路的题,题目中写了“为了在门口展出更多种花”,实际上在该题中,某些种类的花可以一盆都不摆。

小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共 m m m 盆。通过调查顾客的喜好,小明列出了顾客最喜欢的 n n n 种花,从 1 1 1 n n n 标号。为了在门口展出更多种花,规定第 i i i 种花不能超过 a i a_i ai 盆,摆花时同一种花放在一起,且不同种类的花需按标号的从小到大的顺序依次摆列。

正文

花盆问题和背包问题的区别:
背景:

  1. 背包问题中,每个物品的开销可能不同,每种物品数量不限制。
  2. 花盆问题中,每个物品的开销都为1,每种物品数量有限制。

求解目标不同:背包问题是找到最优组合,花盆问题是统计组合数量。

求解过程的差异:

  1. 背包问题不需要考虑物品数量的限制,所以可以从具有当前物品的前某一状态进行转移。
  2. 而花盆问题中,物品数量有限制,具有当前物品的前某一状态可能把物品数量使用完了,所以只能通过未使用当前物品的状态进行转移。

优化思路:

花盆容量小于等于当前物品数量情况下,物品数量的限制就无关紧要了,因为无论如何使用数量都不会超过限制,因此可以当作物品数量无限制来处理。这时,可以通过具有当前物品的前某一状态进行转移。
状态转移公式, d p [ i , j ] dp[i, j] dp[i,j] 表示在有 i 个花盆,只有前 j 种花时的组合数量。
花盆容量小于等于当前物品数量情况下,取 1 ~ i 个或不取当前物品:
d p [ i , j ] = d p [ i − 1 , j ] + d p [ i , j − 1 ] dp[i, j] = dp[i - 1, j] + dp[i, j - 1] dp[i,j]=dp[i1,j]+dp[i,j1]
在花盆容量大于当前物品数量(数量为k)情况下:
d p [ i , j ] = s u m ( d p [ i − k , j − 1 ] . . . d p [ i , j − 1 ] ) dp[i, j] = sum(dp[i - k, j - 1]...dp[i, j - 1]) dp[i,j]=sum(dp[ik,j1]...dp[i,j1])

代码:

def main():
    mod = int(1e6 + 7)
    n, m = map(int, input().split())
    limit = list(map(int, input().split()))
    dp = [1] * (1 + m)
    res = [0] * (1 + m)
    res[0] = 1
    for j in range(n):
        for i in range(1, m + 1):
            dp[i] = sum(res[i - limit[j]:i + 1]) % mod if i > limit[j] else (dp[i - 1] + res[i]) % mod
        dp, res = res, dp
    print(res[-1])

main()
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值