HDU 4389 Template Library Management (贪心+STL)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_37868325/article/details/88229874

题意:

As an experienced ACMer, you must have known the importance of "code template library". With the help of pre-printed code library, you can implement the complicated algorithms correctly and efficiently. However, the size of the library is strictly limited during the contest. For example, you can only take at most 25 pages of printed codes in World Finals. So you must choose carefully which code template should be included. 
Now your team is participating a programming contest whose rules are slightly different from ICPC. This contest consists of N problems, and you must solved them in order: Before you solve the (i+1) thproblem, you must solve the i th problem at first. And solving the ith problem requires a specified code template T i. 
You are allowed to hold M code templates only. At the beginning of the contest, your are holding templates numbered 1, 2, ..., M. During the contest, if the problem you are trying to solve requires code template T i, and T i is happened at your hand (i.e, one of the M code templates you are holding is T i), you can solve it immediately. On the other hand, if you are not holding T i, you must call your friends who are outside the arena for help (yes, it is permitted, not cheating). They can give you the code template you need. Because you are only allowed to hold M code templates, after solving current problem, you must choose to drop the code you get from your friends just now, or to keep it and drop one of the M templates at your hand previously. 
Given the problem sequence in the contest and the limitation M, you want finish all the problems with minimum number of calling your friends.

Input

The first line of each test case contains two numbers N (1 <= N <= 100000) and M (1 <= M <= 100000). The second line contains N numbers T 1, T 2, ..., T N (1 <= T i <= 10 9), indicating the code templates required by each problem.

Output

Output one line for each test case, indicating the minimum number of calling friends for help.

Sample Input

4 3
1 2 3 4
11 3
4 1 2 1 5 3 4 4 1 2 3

Sample Output

1
4

思路:

这个题的贪心思想还是比较好想的,但是,用STL来解决,,因为个人对set不够了解,所以WA+6,前面就用set敲出了代码。但是一直没有调通,,就是重载小于号的问题,

在结构体的set里用find函数时,是根据重载的小于号进行判断等于的,所以,里面的元素都要进行判断,即便没有影响,也要写上,(这个题WA了很多次,就是因为重载小于号写的不完整)

再就是这个题,每次场外求助后,求助得到模板并不一定要替换掉已有的模板,若得到的模板下次使用的最晚,就不用入队了,

代码:(因为重载小于号的问题,一直在修改代码,最后这版,感觉还是比较美观的。

#include<bits/stdc++.h>
using namespace std;
int n,m,ans,a[100005];
int tt[100005];
struct AA
{
    int rt,nex;
    bool operator<(const AA &aa) const
    {
        if(nex==aa.nex) return rt<aa.rt;///一定要有,不然WA。
        return nex>aa.nex;
    }
}pos;
set<AA>s;
set<AA>::iterator it;
map<int,int>ma;
int main()
{
    while(~scanf("%d%d",&n,&m))
    {
        int ans=0;
        ma.clear();
        s.clear();
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        for(int i=n;i>=1;i--)
        {
            if(ma[a[i]]==0)
            {
                tt[i]=0x3f3f3f3f;
            }
            else
            {
                tt[i]=ma[a[i]];
            }
            ma[a[i]]=i;
        }
        for(int i=1;i<=m;i++)
        {
            if(ma[i]==0)
            {
                ma[i]=0x3f3f3f3f;
            }
            pos.rt=i;
            pos.nex=ma[i];
            s.insert(pos);
        }
        for(int i=1;i<=n;i++)
        {
            pos.rt=a[i];
            pos.nex=i;
            it=s.find(pos);
            if(it!=s.end())
            {
                s.erase(it);
                pos.rt=a[i];
                pos.nex=tt[i];
                s.insert(pos);
            }
            else
            {
                ans++;
                pos.rt=a[i];
                pos.nex=tt[i];
                s.insert(pos);
                s.erase(s.begin());
            }
        }
        printf("%d\n",ans);
    }
}

猜你喜欢

转载自blog.csdn.net/qq_37868325/article/details/88229874