栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

【Python】牛生小牛问题(动态规划,考虑生老病死)

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【Python】牛生小牛问题(动态规划,考虑生老病死)

【题目描述】(本校大一的练习题,侵删)

David知道人终有一死,牛也终有一死。所以他决定把牛的死亡也考虑进去,第一年依旧只有两头牛,第4年牛成熟之后每年可以生下一头牛,第7年牛进入老年期,不能生育,第10年牛死亡。David想让聪明的你帮他再计算一下牛的数量。

【输入】

共一行。 输入一个整数n,代表第n年。

【输出】

共一行。 输出一个整数,代表第n年牛的数量。

【解题思路】

在试过若干版本后自己写了一个非常简陋的代码……(算是动规初学小练习)

思路如下:

1.首先明确第i年牛的总数由哪些组成:第i-1年的牛中在第i年仍存活的,和第i年新增的

2.对这两部分进行讨论:

  (1) 第i-1年的牛在第i年仍存活的 = 第i-1年的所有牛 - 正好在第i年死去的牛

(2)第i年新增的 = 第i-1年的牛在第i年仍存活的所有牛 - 这些牛中不具有生育能力的牛(未成熟或失去生育能力) 

3.进行状态描述

  定义一个数组(二维列表)dp,dp中的每一个元素是一个长度为2的子列表。

dp[i][0]表示第i-1年和第i年同时存活的牛的数量,即2.(1)中的部分,dp[i][1]表示第i年新增的牛的数量。

4.写出状态转移方程

首先第i-1年的所有牛 = dp[i-1][0] + dp[i-1][1]

正好在第i年死去的牛,即在6年前出生的牛,也就是dp[i-6][1]

第i-1年和第i年但不具有生育能力的牛 = dp[i - 6][1] + dp[i - 7][1] + dp[i - 8][1] + dp[i - 1][1] + dp[i - 2][1] 

(这里考虑第i-9年及以前出生的牛已经死去,第i-5年一直到i-3年的牛成熟且未失去生育能力(即未过7岁大槛),只需减去除这些年份以外年份出生的牛)

则得到状态转移方程:

  dp[i][0] = dp[i-1][0] + dp[i-1][1] - dp[i-9][1]

  dp[i][1] = dp[i][0] - dp[i - 6][1] - dp[i - 7][1] - dp[i - 8][1] - dp[i - 1][1] - dp[i - 2][1]

【注意】在写具体代码时要考虑i处在什么范围,否则会出现dp的索引为负数的情况从而报错。

def cow(n):
    # dp[i][1]代表第i年和第i-1年都存活的牛的数量(也就是说至少第i-1年它出生了),dp[i][1]代表第i年新出生的牛的数量
    dp = [[0, 0] for i in range(n+1)]
    if 1 <= n < 4:
        dp[0], dp[1] = [0, 0], [0, 2]
        if n > 1:
            dp[2] = [2, 0]
            if n > 2:
                dp[3] = [2, 0]
    else:
        for i in range(4, n+1):
            dp[0], dp[1], dp[2], dp[3] = [0, 0], [0, 2], [2, 0], [2, 0]
            if i < 7:
                dp[i][0] = dp[i - 1][0] + dp[i - 1][1]
                dp[i][1] = dp[i][0] - dp[i - 1][1] - dp[i - 2][1]
            elif i == 7:
                dp[i][0] = dp[i - 1][0] + dp[i - 1][1]
                dp[i][1] = dp[i][0] - dp[i - 6][1] - dp[i - 1][1] - dp[i - 2][1]
            elif 7 < i < 10:
                dp[i][0] = dp[i - 1][0] + dp[i - 1][1]
                dp[i][1] = dp[i][0] - dp[i - 6][1] - dp[i - 7][1] - dp[i - 8][1] - dp[i - 1][1] - dp[i - 2][1]
            else: # 第i年和第i-1年都存活的牛总数=第i-1年的牛总数 - 正好在第i年死去的牛(即9年前出生的牛)的总数
                dp[i][0] = dp[i - 1][0] + dp[i - 1][1] - dp[i - 9][1]
                # 第i年新增的牛总数 = 第i年和第i-1年都存活的牛总数 - 第i年仍未成熟的牛的数量 - 第i年还活着但是已经失去生育能力的牛的总数(即出生年份介于9年前和5年前的牛)
                dp[i][1] = dp[i][0] - dp[i - 6][1] - dp[i - 7][1] - dp[i - 8][1] - dp[i - 1][1] - dp[i - 2][1]
    return dp[n][1] + dp[n][0]  # 第i年的牛总数


n = int(input())
print(cow(n))

【改进】因为初学所以代码中还存在很多需要简化的部分,譬如开头对n小于4的部分的处理,以及肯定有更简单的方法,等学到以后再补充。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/892906.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号