HDU 4398 STL + 贪心

来源:互联网 发布:usr share mysql 编辑:程序博客网 时间:2024/06/04 01:23

STL + 贪心

题意:

​ ACM-ICPC赛事上有n,1~n道题,m个模板(1~m),只有对应的模板才能解出对应的题目,现在规则有点改变,当你没有某一道题的模板的时候能从场外求助获得此模板,但是用完之后你需要从m+1个模板中拿出来一个放在外边,总之就是要保持自己只有m 个模板,问最少可以求助几次?

思路:

​ 若想最少次,那么可以先考虑当模板不够的时候求助一次,然后再放出去一个模板,该放哪一个呢?

自然是用到的模板最靠后的那一个,因为在此之前你还需要用其它模板。

​ 所以贪心思想已经有了,如何实现?

​ 首先肯定需要记录m个模板和使用的下一次的位置,set不能放重复元素,但是可以存放模板保留情况,以便快速查找。multiset可以借用排序,从而快速找到和重置模板的信息。

#include <iostream>#include <cstdio>#include <cstring>#include <set>#include <map>using namespace std;const int maxn = 100005;int a[maxn],n,m;int Next[maxn];struct Template{    int v;    int next;};struct classcmp{    bool operator()(const Template &a,const Template &b) const    {        return a.next < b.next;     //按照从小到大自动排序,end()为next最大    }};multiset<Template,classcmp>TempNext;multiset<Template>::iterator it1;set<int>s;set<int>::iterator it2;map<int,int>mp;int main(int argc, char const *argv[]){    freopen("in.txt","r",stdin);    while(scanf("%d%d",&n,&m) != EOF) {        for(int i = 1;i <= n; i++)            scanf("%d",&a[i]);        mp.clear();        for(int i = n;i >= 1; i--) {            if(mp[a[i]]) Next[i] = mp[a[i]];            else Next[i] = n + 1;            mp[a[i]] = i;        }        TempNext.clear();        s.clear();        for(int i = 1;i <= m; i++) {            if(!mp[i]) mp[i] = n + 1;            Template temp;            temp.v = i;            temp.next = mp[i];            s.insert(i);            TempNext.insert(temp);        }        int ans = 0;        for(int i = 1;i <= n; i++) {            it2 = s.find(a[i]);            if(it2 != s.end()) {                Template temp;                temp.v = a[i];                temp.next = i;                TempNext.erase(temp);                temp.next = Next[i];                TempNext.insert(temp);            }            else {                it1 = TempNext.end();                it1--;                ans++;                if(Next[i] < (*it1).next) {                    s.erase((*it1).v);                    TempNext.erase(it1);                    Template temp;                    temp.next = Next[i];                    temp.v = a[i];                    s.insert(a[i]);                    TempNext.insert(temp);                }            }        }        printf("%d\n",ans);    }    return 0;}
原创粉丝点击