P1048 采药(洛谷)

P1048 采药(洛谷)

传送门

中文题面,不描述。
这道题记忆化搜索和dp都可以实现,实际上就是一个0-1背包问题。选和不选获得一个最大值输出即可。
这里给出两种解决方案。

记忆化搜索:
dp[i][j]表示第i件物品下,时间耗费为j的最大价值。
dp[][]初始话为-1
因为在我们dfs内部如果当前i大于了m的话,直接返回的是0,是无效的。(也会算作已经处理的情况)
当总的时间j大于等于采集第i件物品的时间时,那么对于第i件物品,有选和不选两种选择,维护最大的即可。
当总的时间j大于采集第i件物品的时间时,只能放弃第i件物品。继续搜下去。
最后输出即可。

dp:
这个是0-1背包
dp[i]表示时间耗费为i时的最大价值。
我们就可以二重循环遍历即可。
对于第i件物品,从总的时间t开始到tim[i]结束。维护dp[j]的一个最大值。从前面的dp[]转移过来维护一个最大值即可。
记得初始话dp[]为0

对应的还有一道题是疯狂的采药,是一道多重背包问题~
传送门
跟0-1背包不同的是多重背包可以无限次数的获取,所以多重背包从前往后,0-1背包从后往前;
这道题对应的关键部分是:

for (int i = 1; i <= m; i++)
	{
		for (int j = tim[i]; j <= t; j++)
		{
			dp[j] = max(dp[j], dp[j - tim[i]] + value[i]);
		}
	}

记忆化搜索的代码部分:

#include <bits/stdc++.h>
#define mst(a, n) memset(a, n, sizeof(a))
using namespace std;
const int N = 1e3 + 10;

int tim[N];
int value[N];
int t, m;
int dp[N][N];

int dfs(int x, int y)
{
	if (x > m)
	{
		return 0;
	}
	if (dp[x][y] != -1)
	{
		return dp[x][y];
	}
	if (y >= tim[x])
	{
		return dp[x][y] = max(dfs(x + 1, y), dfs(x + 1, y - tim[x]) + value[x]);
	}
	else
	{
		return dp[x][y] = dfs(x + 1, y);
	}
}

int main()
{
	mst(dp, -1);
	cin >> t >> m;
	for (int i = 1; i <= m; i++)
	{
		cin >> tim[i] >> value[i];
	}
	cout << dfs(1, t) << endl;
	return 0;
}

dp代码部分:

#include <bits/stdc++.h>
#define mst(a, n) memset(a, n, sizeof(a))
using namespace std;
const int N = 1e3 + 10;

int tim[N];
int value[N];
int t, m;
int dp[N];

int main()
{
	cin >> t >> m;
	for (int i = 1; i <= m; i++)
	{
		cin >> tim[i] >> value[i];
	}
	for (int i = 1; i <= m; i++)
	{
		for (int j = t; j >= tim[i]; j--)
		{
			dp[j] = max(dp[j], dp[j - tim[i]] + value[i]);
		}
	}
	cout << dp[t] << endl;
	return 0;
}
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

娃娃酱斯密酱

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

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

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

打赏作者

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

抵扣说明:

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

余额充值