我是靠谱客的博主 无私咖啡,最近开发中收集的这篇文章主要介绍Cooking Time Gym - 101498F 贪心,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

题目链接:
Cooking Time
题目大意:
有一个冰箱,有N个调味品,一开始所有调味品都在冰箱内.外面最多放置 K个调味品
你要按给定的顺序来拿取调味品,如果外面有调味品那么直接取用即可,如果没有需要打开冰箱,如果外面放置数达到K了,那么需要放回一个.
现在要求最少要开几次冰箱

分析:
贪心地去放回调味品,将后面没有再继续用的调味品放回.
如果都一样那么任意返回一个即可.原因是无论重复次数和先后顺序多少,都要记一次取用.
那么用 pii 单调单调队列就可以了.

预处理每个调味品编号和下一个相同调味品的位置 nxt[i]

实际上是一个线性过程

代码实现;

#include<bits/stdc++.h>
using namespace std;
#define pb push_back
#define inf 0x3f3f3f3f
#define mem(s,t) memset(s,t,sizeof s)
typedef pair<int,int> pii;
const int MAXN =1e5+10;
int n,k;
priority_queue<pii,vector<pii> > pq;
map<int,int> m;
int a[MAXN],lst[MAXN],nxt[MAXN],inque[MAXN];
int main() {
int T;
scanf("%d",&T);
while(T--){
m.clear();
while(!pq.empty()) pq.pop();
mem(nxt,0);
mem(inque,0);
scanf("%d%d",&n,&k);
int cnt=0;
for(int i=0;i<n;i++){
scanf("%d",&a[i]);
if(!m.count(a[i])) m[a[i]]=++cnt;//重新编号
lst[i]=n;
inque[i]=0;
nxt[i]=0;
}
for(int i=0;i<n;i++) a[i]=m[a[i]];
for(int i=n-1;i>=0;i--){//预处理下一个位置
nxt[i]=lst[a[i]];
lst[a[i]]=i;
}
int ans=0;
for(int i=0;i<n;i++){
//cout<<inque[a[i]]<<endl;
if(inque[a[i]]){
pq.push(make_pair(nxt[i],a[i]));//将下一个入队
continue;
}
if(k){
k--;
ans++;
inque[a[i]]=1;
pq.push(make_pair(nxt[i],a[i]));
}
else {
ans++;
while(!inque[pq.top().second]) pq.pop();//将已经不在队里的清空
inque[pq.top().second]=0;
pq.pop();
inque[a[i]]=1;
pq.push(make_pair(nxt[i],a[i]));
}
}
cout<<ans<<endl;
}
return 0;
}

最后

以上就是无私咖啡为你收集整理的Cooking Time Gym - 101498F 贪心的全部内容,希望文章能够帮你解决Cooking Time Gym - 101498F 贪心所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(41)

评论列表共有 0 条评论

立即
投稿
返回
顶部