[洛谷P2088] 果汁店的难题 解题记录

[洛谷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;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值