专题二K采药

题目链接:

采药

题目如下:
思路

这就是一道背包dp中最原始的01背包问题。

先介绍什么是dp(动态规划),动态规划是一种通过把原问题分解为相对简单的子问题的方式求解复杂问题的方法。

然后说一下什么转移方程,转移方程很简单就是:大问题=f(小问题)。

解一道dp题目最重要的是找到它的转移方程,一般转移方程写出来,问题就解决了。

简单介绍完之后,我们回到题目:

题目有两个变量:药的数量和可以采药的时间。然后我们把这两个变量一个一个细分,比如只采前i个药,有j时间的结果。然后我们就可以发现我们把一个问题给划分成M*T个问题,我们用一个二维数组来进行存储f[i][j],表示只采前i个药,有j时间的结果。

然后我们来找状态转移方程,首先这道题中药有两种状态:采和不采。如果我们要采摘药的话,会消耗采摘的时间(设为t),获得价值v,结果为f[i-1][j-t]+v,而不采药的话,结果为f[i-1][j],即上一个的结果,然后我们取两个之间的最大值,就是f[i][j]的结果。那么转移方程就出来了:

这道题也就结束了。我们开个二重循环遍历i和j,最后f[M][T]就是我们需要的答案。

推荐关于讲解背包问题的视频

代码采用一维数组:
#include <stdio.h>
int v[111];//价值
int r[111];//所需时间
int dp[1111];

int main() {
    int i, j, T, M;
    scanf("%d%d", &T, &M);
    for (i = 1; i <= M; i++) {
        scanf("%d%d", &r[i], &v[i]);
    }
    for (i = 1; i <= M; i++) {
        for (j = T; j >= 1; j--) {
            if (j >= r[i])
                dp[j] = (dp[j] > dp[j - r[i]] + v[i]) ? dp[j] : (dp[j - r[i]] + v[i]);
        }
    }
    printf("%d", dp[T]);
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值