【二分】洛谷P2920,P2985做题小记

这两道题都是贪心+二分答案。

P2920 题解

洛谷P2920的贪心策略是将每组数据按照结束时间从小到大排序,让结束时间早的任务先做,结束了一个任务后马上做下一个任务。然后就是二分答案,最早是0,最晚是结束时间最早的任务减去其所需要的时间假设是x,故l=0,r=x+1(在我写的二分模板里面,答案返回的是l,结束条件是l+1<r)。我还定义了一个判断函数jd,传入开始时间,对于每个任务,如果上一个任务结束时间加上本任务耗时小于等于最晚时间,则没问题,再看下一个任务。否则就返回0,提前结束判断。如果全部任务按照我的策略都能在最晚时间前结束,则jd函数返回1。如果jd函数返回1,说明开始时间还可以往后延,所有l=mid;否则r=mid。输出答案前,把l传入函数jd,如果返回0,说明无法保证所有任务按时完成,输出-1。否则输出l。

cpp 复制代码
#include <bits/stdc++.h>
#define int long long
using namespace std;

struct work {
	int t, s;
} w[1005];

bool cmp(work w1, work w2) {
	if (w1.s > w2.s)
		return 0;
	if (w1.s == w2.s && w1.t > w2.t)
		return 0;
	return 1;
}
int n, l, r;

bool jd(int x) {
	for (int i = 1; i <= n; i++) {
		if (x + w[i].t > w[i].s)
			return 0;
		x += w[i].t;
	}
	return 1;
}

signed main() {
	cin >> n;
	for (int i = 1; i <= n; i++)
		cin >> w[i].t >> w[i].s;
	sort(w + 1, w + n + 1, cmp);
	int l = 0, r = w[1].s - w[1].t + 1;
	bool flag = 1;
	while (l + 1 < r) {
		int mid = (l + r) / 2;
		if (jd(mid) == 1)
			l = mid;
		else
			r = mid;
	}
	if (jd(l))
		cout << l;
	else
		cout << -1;
	return 0;
}

P2985题解

这道题的细节比较多,这道题l=0,r=所有巧克力开心值总和+1。定义jd函数传入参数x,x代表所有天里面的最小开心值,如果能保证每天的开心值都大于等于x,则jd函数返回1,否则返回0。如果jd函数返回1,那么最低开心值可能可以再取高一点,l=mid。如果返回0,r=mid。这道题要注意开long long;在记录每块巧克力被第几天吃掉的时候,因为jd函数一旦发现最后一天达到了最短开心值后,就结束while循环。可能导致的一个问题是吃到第j块(j<n)的时候就达到最短开心值了,第j+1块以后的巧克力被吃的天数没被记录。所以在得到最小开心值的最大值后我们要写一个判断,如果该巧克力被吃的天数为0,就认为是第d天被吃的。

cpp 复制代码
#include <bits/stdc++.h>
#define ll long long
using namespace std;
ll n, d, l, r, h[100005], s;
ll a[100005];

bool jd(ll x) {
	ll t = 0, j = 1;
	memset(a, 0, sizeof(a));
	for (int i = 1; i <= d; i++) {
		while (j <= n && t < x) {
			t += h[j];
			a[j] = i;
			j++;
		}
		if (t < x)
			return 0;
		t = t / 2;
	}
	return 1;
}
int main() {
	cin >> n >> d;
	for (int i = 1; i <= n; i++) {
		cin >> h[i];
		s += h[i];
	}
	l = 0, r = s + 1;
	while (l + 1 < r) {
		ll mid = (l + r) / 2;
		if (jd(mid) == 1)
			l = mid;
		else
			r = mid;
	}
	if(jd(l)){
		cout << l << endl;
		for (int i = 1; i <= n; i++){
			if(a[i]) cout << a[i] << endl;
			else cout<<d<<endl;
		}
			
	}
	return 0;
}
相关推荐
qq_4101942926 分钟前
.NET 8.0 下基于 PaddleOCRSharp 的离线文字识别落地指南
算法·.net
Omics Pro30 分钟前
1个月2轮融资!长寿虚拟细胞
数据库·人工智能·算法·机器学习·自然语言处理
residual_fan31 分钟前
航空发动机故障诊断专用智能体(六):实际机队健康管理中的应用考量与展望
人工智能·算法·数据挖掘·数据分析
码匠许师傅40 分钟前
【C++三方组件】cxxopts:轻量首选的命令行解析
c++
hansang_IR1 小时前
【讲解】CSP-S2026 第一轮初赛
c++·算法
hanlin031 小时前
刷题笔记:力扣第76题-最小覆盖子串
笔记·算法·leetcode
Zane19941 小时前
比较排序跑不出O(nlogn)是数学上证明过的,计数、桶、基数排序凭什么能绕开这堵墙
算法·排序算法
tiger8651 小时前
大语言模型面试和题解,梳理中国主流开源 LLM 系列的发展脉络、技术路线与工程取舍
人工智能·gpt·深度学习·算法·自然语言处理·面试·transformer
Methy1 小时前
IoTHub半个月崩了五次?都是裸rethrow惹的祸
服务器·c++·后端
我不会起名字3221 小时前
一天一道力扣Hot100(36):深度优先算法---组合总和
数据结构·c++·后端·python·算法·go