题目:http://www.wikioi.com/problem/2069/
分析:
首先这个问题比较复杂,涉及到两个重要的考虑点,一个是当前拿来的颜色是否保留,一个是若保留后那么应该把当前盘子的哪个颜色去掉。
先从简单考虑,假设不考虑当前颜色是否保留,规定如果盘子里没有的颜色拿来后就必须放入盘子中,同时从盘子中去掉一个颜色,那么问题就是现在删除哪个颜色好:
最直接的想法就是删去在后面出现次数最少的颜色,因为后面出现次数越多我把保留在盘子里就需要换更少次。那么这么想正确吗?
举个栗子:盘子里的颜色是1 2 3 给出的序列是4 1 1 4 2 2 2 3 3 3 3
那么根据我们的贪心策略盘子的颜色依次是:
4 2 3(+1)
1 2 3(+1)
1 2 3
4 2 3(+1)
……(后面没有了)
总共是3次
而如果我们第一次删的不是1而是3,则只需2次
这是因为"1"“迫在眉睫”,仔细想想,即使一个颜色在后面出现的次数再多再多,但在后面第一次出现的位置离现在位置很远很远,为什么要一直让它占着位置呢?
于是我们的贪心策略就是每次删除的盘子中所有颜色中在后面最晚出现(指第一次出现最晚)的颜色!
再加上另一个问题,就是考虑当前拿来的颜色是否要跟盘子中的换,这很好解决,我们可以理解成盘子容纳的颜色数变成了m+1个,我们将这个颜色放进去,然后再m+1个颜色中取按照第一问的原则删除最晚出现(第一次出现最晚)的颜色
综上,我们的贪心策略是:
对于当前处理颜色:
①盘子里有:直接跳过
②盘子里没有:
(1)若盘子里的所有颜色中最晚出现的颜色的位置比当前处理颜色紧接着的下一个位置要靠前,那么就不用把处理的颜色加入盘子中
(2)…………………………………………………………………………………………………………………………要靠后,那么就去掉最晚出现的颜色并把新颜色加入盘子
对于上面这个过程,当然用堆维护,鉴于要快速知道一个颜色的下一个位置,所以要用链表预处理