2.采药-01背包

本文介绍了如何解决NOIP2005普及组的采药问题,探讨了贪心算法和动态规划在解决问题时的区别。通过举例说明,解释了为什么在某些情况下贪心策略可能不适用,并提供了01背包问题的动态规划解决方案,详细阐述了状态转移方程和初始状态的设定。最后,给出了完整的C++代码实现。
摘要由CSDN通过智能技术生成

[NOIP2005 普及组] 采药 - 洛谷


解题思路:

1.看到此题,很容易想到贪心算法的最优装载问题,那什么时候用贪心,什么时候用DP呢?贪心是比较“目光短浅”的,只考虑当前情况下应该放哪一株草药,那么在排序过程中,肯定是优先选择单位时间内价值更大的草药,当以这种策略选择的时候,每次的选择都是不可逆的,即当把价值比最高的放入背包后,不会再拿出来,而DP是根据背包的容量和价值随时在调整

2.举个例子:当背包容量为100的时候,有两株草药,时间和价值分别是20  90与100 100,很明显前者的价值比更高,但是一旦放入第一株草药后,第二株放不下了,可是放第二株才是正解,价值更高,通常遇到这种题目要去构造一组数据,利用反证等方法推翻一种策略

3.如果是DP问题,可以明显看出是01背包问题,每个物品只有一种,并且有两种选择,放或不放

4.设置状态:dp【i】【j】表示前i种物品在j时刻时的最大价值

5.状态转移:如果第i种物品不放的话,那么j时刻的价值也就是前i-1种物品的价值,即dp[i][j]=dp[i-1][j],如果第i种物品放入的话,那么背包意味着牺牲容量,前i-1中的容量就缩小为j-tt[i],然后再加上第i种物品的价值,放与不放取较大值,dp[i][j]=max(dp[i-1][j-tt[i]]+v[i],dp[i-1][j])

6.初始状态:当时刻j为0的时候,那么价值为0,即dp[i][0]=0,当物品为0的时候,价值也为0 ,即dp[0][j]=0

7.求解目标值dp[m][T]


#include<bits/stdc++.h>
using namespace std;
int tt[110],value[110],dp[110][1005];
int main()
{
	int t,m;
	cin>>t>>m;
	
	for(int i=1;i<=m;i++)//将每株草药的时间和价值存入数组 
	{
		cin>>tt[i]>>value[i];
	}
	
	for(int i=1;i<=m;i++)//枚举每株草药 
	{
		for(int j=1;j<=t;j++)//枚举每个时刻 
		{
			if(j>=tt[i])//如果该时刻可以采摘这株草药 
			{
				dp[i][j]=max(dp[i-1][j-tt[i]]+value[i],dp[i-1][j]);//选择较大价值 
			}
			else
			dp[i][j]=dp[i-1][j];//否则的话继承前i-1种草药的价值 
		}
	}
	
	cout<<dp[m][t];//输出目标值 
	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值