[洛谷P2088] 果汁店的难题 解题记录
题意简述
有
K
K
K 台干净的榨汁机,每台榨汁机只能榨一种果汁,如果要换果汁,那就得清洗一次。
现在有
N
N
N 个订单,每个订单给出一种果汁,求最少清洗次数
题目分析
如果直接模拟的话是肯定过不了的,考虑贪心。
如果当前没有干净的榨汁机了,并且队列头部的果汁必须要清洗一台榨汁机才行,为了增加当前榨汁机能榨的果汁次数尽可能多(换的尽可能少),就需要清洗榨汁机中下一个同类果汁与当前订单距离最远的,因为它最长时间用不到。用数组记录下标,模拟即可。
AC Code
#include<bits/stdc++.h>
#define arrout(a,n) rep(i,1,n)std::cout<<a[i]<<" "
#define arrin(a,n) rep(i,1,n)std::cin>>a[i]
#define rep(i,x,n) for(int i=x;i<=n;i++)
#define dep(i,x,n) for(int i=x;i>=n;i--)
#define erg(i,x) for(int i=head[x];i;i=e[i].nex)
#define dbg(x) std::cout<<#x<<":"<<x<<" "
#define mem(a,x) memset(a,x,sizeof a)
#define all(x) x.begin(),x.end()
#define arrall(a,n) a+1,a+1+n
#define PII std::pair<int,int>
#define m_p std::make_pair
#define u_b upper_bound
#define l_b lower_bound
#define p_b push_back
#define CD const double
#define CI const int
#define int long long
#define il inline
#define ss second
#define ff first
#define itn int
CI N=105;
int k,n,ans,a[N];
std::queue<int> q;
std::vector<int> idx[N];
signed main() {
std::cin>>k>>n;
rep(i,1,n) {
int x;
std::cin>>x;
idx[x].p_b(i);
q.push(x);
}
rep(i,1,n) {
int x=q.front();
q.pop();
int flag=0;
rep(j,1,k) {
if(a[j]==x) {
flag=1;
break;
}
}
if(!flag) {
if(a[0]<k) {
a[++a[0]]=x;
continue;
}
int lst,max=0;
rep(j,1,a[0]) {
int id;
if(std::u_b(all(idx[a[j]]),i)==idx[a[j]].end()) {
id=-1;
} else {
id=std::u_b(all(idx[a[j]]),i)-idx[a[j]].begin();
}
if(id==-1) {
max=LLONG_MAX;
lst=j;
continue;
}
if(idx[a[j]].at(id)>max) {
max=idx[a[j]].at(id);
lst=j;
}
}
a[lst]=x;
ans++;
}
}
std::cout<<ans;
return 0;
}