专栏文章

题解:B4304 [蓝桥杯青少年组省赛 2024] 通关游戏的最少能量值

B4304题解参与者 1已保存评论 0

文章操作

快速查看文章及其快照的属性,并进行相关操作。

当前评论
0 条
当前快照
1 份
快照标识符
@mip80y7d
此快照首次捕获于
2025/12/03 07:40
3 个月前
此快照最后确认于
2025/12/03 07:40
3 个月前
查看原文

Background

算法:二分答案、贪心。
首先理解题意,共有三个重要的信息,我们可以理解为:门槛花费报酬。其中报酬的值为门槛减去花费。

Solution

简单思考,我们可以得出贪心策略
  1. 先完成回报多的任务,这样才能留下更多给回报少的。
  2. 若回报相同,先完成门槛高的,不然后面无法完成。

由此,我们可以用二分答案
  1. 直接枚举希望的最小值,检验是否满足全部任务都能完成。
  2. 若可以,找更小的满足值;若不可以,找较大的可能值。

Code

细节可以看注释。
CPP
#include<bits/stdc++.h>
#define N 100005
using namespace std;

class Quick_IO
{
  public:
	template<typename T>
	void read(T &r)
	{
		T x = 0, f = 1;
		char ch = getchar();
		while (ch < '0' || ch > '9')
		{
			if (ch == '-') f = -1;
			ch = getchar();
		}
		while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
		r = x * f;
	}
	template<typename T, typename... Args>
	void read(T &tmp, Args &... tmps)
	{
		read(tmp);
		read(tmps...);
	}
} io;

int n, M;
struct node	//门槛,花费,回报
{
	int need, cost, reward;
} a[N];
bool operator < (node x, node y)	//排序
{
	if (x.reward == y.reward) return x.need > y.need; //回报一样的话先完成门槛高的
	return x.reward > y.reward;	//先完成回报多的
}

bool Judge(int aim)	//判断
{
	for (int i = 1; i <= n; i++)
	{
		//注意二分初始区间已经排除了买不起的可能,因此不用再if
		if (aim < a[i].need) return 0;
		aim -= a[i].cost;
	}
	return 1;
}

signed main()
{
	io.read(n);
	for (int i = 1; i <= n; i++)
	{
		io.read(a[i].need, a[i].cost);
		a[i].reward = a[i].need - a[i].cost;
		M += a[i].cost;
	}
	sort(a + 1, a + 1 + n);


	int L = M, R = 2e9, mid, ans = 2e9;
	while (L <= R)	//二分答案
	{
		mid = L + (R - L) / 2;
		if (Judge(mid)) ans = mid, R = mid - 1;
		else L = mid + 1;
	}
	cout << ans;
}

评论

0 条评论,欢迎与作者交流。

正在加载评论...