奶牛繁殖问题(动态规划实现)

目录

问题背景

递推公式的逻辑

递推公式的推导

动态规划的实现

示例输出

总结


问题背景

假设农场中有一头母牛,它从第4年开始每年生一头小牛,且每头小牛也是母牛,同样从第4年开始每年生一头小牛。问第 i 年农场中有多少头牛。

递推公式的逻辑

  1. 定义状态

    • dp[i] 表示第 i 年农场中牛的总数。

  2. 递推关系

    • i 年的牛的数量由两部分组成:

      • dp[i - 1]:表示第 i-1 年的牛的数量。这些牛在第 i 年仍然存在。

      • dp[i - 4]:表示第 i-4 年的牛的数量。这些牛在第 i-4 年出生,到第 i 年时已经满4岁,可以生育新的小牛。

    • 因此,第 i 年的牛的总数等于第 i-1 年的牛的数量加上第 i-4 年的牛的数量。

  3. 递推公式

    dp[i]=dp[i−1]+dp[i−4]dp[i]=dp[i−1]+dp[i−4]

递推公式的推导

  1. 基本情况

    • 第1年:只有1头母牛,dp[1] = 1

    • 第2年:仍然只有1头母牛,dp[2] = 1

    • 第3年:仍然只有1头母牛,dp[3] = 1

    • 第4年:母牛开始生小牛,dp[4] = 2(1头母牛 + 1头小牛)。

  2. 递推过程

    • 第5年:dp[5] = dp[4] + dp[1] = 2 + 1 = 3

    • 第6年:dp[6] = dp[5] + dp[2] = 3 + 1 = 4

    • 第7年:dp[7] = dp[6] + dp[3] = 4 + 1 = 5

    • 第8年:dp[8] = dp[7] + dp[4] = 5 + 2 = 7


动态规划的实现

以下是使用动态规划实现该递推公式的代码:

#include <stdio.h>

int countCows(int n) {
    if (n <= 0) return 0;
    if (n == 1 || n == 2 || n == 3) return 1;
    if (n == 4) return 2;

    int dp[n + 1];  // 动态规划数组
    dp[0] = 0;      // 第0年没有牛
    dp[1] = 1;      // 第1年有1头牛
    dp[2] = 1;      // 第2年有1头牛
    dp[3] = 1;      // 第3年有1头牛
    dp[4] = 2;      // 第4年有2头牛

    // 填充动态规划数组
    for (int i = 5; i <= n; i++) {
        dp[i] = dp[i - 1] + dp[i - 4];  // 递推公式
    }

    return dp[n];  // 返回第n年的牛的数量
}

int main() {
    int years = 20;
    int totalCows = countCows(years);
    printf("%d年之后共有%d头牛\n", years, totalCows);
    return 0;
}

示例输出

输入:

years = 20

输出:

20年之后共有345头牛

总结

  • 递推公式 dp[i] = dp[i - 1] + dp[i - 4]; 的逻辑是基于牛的繁殖规则:第 i 年的牛的数量等于第 i-1 年的牛的数量加上第 i-4 年的牛的数量。

  • 动态规划通过存储中间结果避免了重复计算,显著提高了效率。

  • 该递推公式适用于类似的递推问题,如动物的繁殖、资源的增长等。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

JJJ69

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值