洛谷 P12916 [POI 2021/2022 R1] 剪辑师 / Montażysta 题解

题目传送门:P12916 [POI 2021/2022 R1] 剪辑师 / Montażysta

闲话

P4053 [JSOI2007] 建筑抢修 的多倍经验来的,思路一样,做了本题的可以过去看看。

题意大意

\(n\) 个视频。第 \(i\) 个视频可以用 \(t_i\)\(d_i\) 来描述。制作第 \(i\) 个视频需要 \(t_i\) 天,要在第 \(d_i\) 天结束前做完。

从第 \(1\) 天开始工作,问最多可以做多少个视频。

思路分析

P4053 [JSOI2007] 建筑抢修 一样,是一个反悔贪心,只不过多了一个方案输出。

贪心策略如下。

设当前的天数为 \(now\)。因为每个视频对答案提供的价值都最多为 \(1\) 而截止时间早的视频在时间增加的过程中会越早不能提供价值,所以我们先做截止时间早的视频。我们就以截止时间 \(d_i\) 为关键字将视频从小到大排序。

当目前视频制作数 \(ans\) 一定时,我们还是想让 \(now\) 尽量小一点。从这一点就可以想出反悔机制:做到第 \(i\) 个视频时,如果时间充裕 \(t_i + now \le d_i\),我们就做这个视频,\(ans + 1\),并将这个视频加入以花费时间 \(t_i\) 为关键字的大根堆中;如果 $ t_i + now > d_i$ ,那么取出大根堆的堆顶,将当前视频替换掉在堆顶的视频,\(now\) 减去堆顶,再将本视频存入大根堆里,\(ans\) 值不变。

如此将 \(n\) 个视频都扫一遍,就可以得出答案 \(ans\)

还存在优先队列里的视频,就是我们选出来要做的视频,我们将队里的视频取出,以截止时间 \(d_i\) 为关键字对这些视频从小到大排序,然后按顺序输出即可。

其余细节实现请见代码。

代码

#include <bits/stdc++.h>
using namespace std;

long long n, ans, now;
long long a, b;
struct node{
	long long idx, t, d;//分别为视频编号,花费时间,截止时间
	bool operator < (const node &er_mao)const{//以花费时间为关键字从大到小排序
		return er_mao.t > t;
	}
}num[600010];
long long cnt;
priority_queue <node> q; //优先队列实现大根堆维护花费时间

bool cmp(node x, node y){//以截止时间为关键字从小到大排序
	return x.d < y.d;
}
int main(){
	ios::sync_with_stdio(false);//解绑操作,加快输入输出速度
	cin.tie(0);
	cout.tie(0);
    
	cin >> n;//输入
	for(int i = 1; i <= n; i++){
		cin >> num[i].t >> num[i].d;
		num[i].idx = i;//别忘记将编号也存起来,因为输出时要输出编号
	}
	
	sort(num + 1, num + 1 + n, cmp);//排序
    
	for(int i = 1; i <= n ;i++){
		now += num[i].t;//先选这一个视频
		q.push(num[i]);
        
		if(now <= num[i].d){//时间足够做完这个视频
			ans++;
		}else{//反悔操作
			now -= q.top().t;//丢掉花费时间最长的视频
			q.pop();
		}
	}
    
	while (!q.empty()){//还在队列里的就是选出的视频
		cnt++;
		num[cnt] = q.top();
		q.pop();
	}
    now = 1; //因为是从第一天开始,所以now设为1
	sort(num + 1, num + 1 + cnt, cmp);//将选出的视频以截止时间为关键字排序
    
	cout << ans << '\n';//输出视频个数
	for(int i = 1;  i <= cnt; i++){//输出方案
		cout << num[i].idx << " " << now << '\n';
		now += num[i].t;
	}
	return 0;
} 

写在最后

帮到你的话请点赞题解喵,点赞题解谢谢喵

posted @ 2025-07-21 21:06  牢毛暂时好耶  阅读(15)  评论(0)    收藏  举报