本文主要是介绍采药(详细分析(✪ω✪)(✪ω✪)),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
解题思路:
首先我们要创建两个数组储存采草药的时间以及采草药的价值,然后再创建一个二维数组用来储存在规定时间内所能采到草药的最大总价值。
时间: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♪(・ω・)ノ
这篇关于采药(详细分析(✪ω✪)(✪ω✪))的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!