采药(详细分析(✪ω✪)(✪ω✪))

解题思路:

首先我们要创建两个数组储存采草药的时间以及采草药的价值,然后再创建一个二维数组用来储存在规定时间内所能采到草药的最大总价值。

时间:time[1050]={0};

价值:val[1050]={0};

二维数组:dp[1050][1050]={0};

 这个二维数组呢,先表示为dp[i][j],[i]这一部分就表示我们采摘草药的序号,[j]这一部分呢,就用来储存我们能够采摘的草药的价值了。

下面来我来为大家介绍一下如何使用这个二维数组

既然是二维数组,那使用它就一定要两个循环

 for(long long i=1;i<=m;i++)
    {
        for(long long j=t;j>=0;j--)
        {
            if(j>=time[i])
            {
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-time[i]]+val[i]);
            }
            else dp[i][j]=dp[i-1][j];
        }
    }

这里的t,m就是题上所给的T,M的意思

最外层循环,由1到m,将每个草药都遍历一遍

第二层循环以及循环体,也就是本题的精华部分,j从t开始递减至0,目的就是为了让这个二维数组能够储存能够采到的草药的最大总价值

以样例为例,

 列出数组中所有的数据如下:

i\j

70

69

68

67

66

65

64

……

5

4

3

2

1

0

1

0

0

0

0

0

0

0

0

0

0

0

0

0

0

2

1

1

0

0

0

0

0

0

0

0

0

0

0

0

3

3

2

2

2

2

2

2

2

2

2

2

2

2

0

因为采摘第一个草药所需的时间为71,而总的采药时间为70,所以当i为1时,能够采摘到的草药的价值为0。

采摘第二个草药所需的时间为69,总的采药时间为70,所以当j>=69时,都可以获得这个草药的价值。

第三行的结果就要涉及到循环体了

            if(j>=time[i])
            {
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-time[i]]+val[i]);
            }
            else dp[i][j]=dp[i-1][j];

这里的判断条件是“剩下的采摘时间j是否大于采摘第i株草药所需的时间time[i]”,如果大于,那么就要减去相应的时间,因为采摘草药总时间是一定的,采摘任何一株草药都会消耗,应该将该草药的价值加上上一行[j-time[i]]处草药的价值,并与上一行j处进行比较,确保在此时间点上所采的药的价值是最大的。

如果小于,那么将上一行的数据移下来就可以了。

那最后的答案就储存在dp[m][t]中。

总代码:

#include<iostream>
using namespace std;
long long dp[1050][1050]={0};
int main()
{
    long long t,m;
    long long time[1050]={0};
    long long val[1050]={0};
    cin>>t>>m;
    for(long long i=1;i<=m;i++)
    {
        cin>>time[i]>>val[i];
    }
    for(long long i=1;i<=m;i++)
    {
        for(long long j=t;j>=0;j--)
        {
            if(j>=time[i])
            {
                dp[i][j]=max(dp[i-1][j],dp[i-1][j-time[i]]+val[i]);
            }
            else dp[i][j]=dp[i-1][j];
        }
    }
    cout<<dp[m][t];
}

希望各位大佬多提意见,不足之处还请指出。

也希望各位互相关注点赞,共同进步!Thanks♪(・ω・)ノ

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值