E. Cubes codeforce 180/E

来源:互联网 发布:房产拍卖淘宝司法拍卖 编辑:程序博客网 时间:2024/04/30 11:02



Let's imagine that you're playing the following simple computer game. The screen displays n lined-up cubes. Each cube is painted one of m colors. You are allowed to delete not more than k cubes (that do not necessarily go one after another). After that, the remaining cubes join together (so that the gaps are closed) and the system counts the score. The number of points you score equals to the length of the maximum sequence of cubes of the same color that follow consecutively. Write a program that determines the maximum possible number of points you can score.

Remember, you may delete no more than k any cubes. It is allowed not to delete cubes at all.

Input

The first line contains three integers nm and k (1 ≤ n ≤ 2·105, 1 ≤ m ≤ 105, 0 ≤ k < n). The second line contains n integers from 1to m — the numbers of cube colors. The numbers of colors are separated by single spaces.

Output

Print the maximum possible number of points you can score.

Sample test(s)
input
10 3 21 2 1 1 3 2 1 1 2 2
output
4
input
10 2 21 2 1 2 1 1 2 1 1 2
output
5
input
3 1 21 1 1
output
3

看到这道题想法不是很多,肯定不能一种一种判断k个容错的最长同种序列,而且还是如此长的一个序列。如何进行判断呢?既然是动态规划的题目,状态转移,这个状态转移与种类无关,可能要还某种特殊的表示方法?

每种的数量这种信息肯定没什么作用,k个和k-1个差别也可能是天壤之别,状态转移应该是根据m的吧,但是m的数量级否定了这个可能性。而k应该是作为一个一开始就知道的值代入的。

旁边有一些暗示,二分法,两个指针。不太想往这个暗示的方面去想,不过可以一试。


看了别人博客中的解法,用了Vector这个数据结构,基本上做的都用了这个数据结构。

没看出来哪里动态规划了其实,不过惊奇的是,它居然是从第一个元素到最后一个元素,一个个进行二分查找找到k距离可以容纳的个数,nlgn的复杂度原来也可以通过啊。长知识了。

下面附上网上找到的代码,过两天在自己试着写写:

#include<stdio.h>
#include<vector>
using namespace std;
#define N 200009
int a[N],p[N];
int main()
{
   vector<int>v[N];//二维的,每一行记录的是 一个数 在输入时的每个下标
   int n,m,k,i;
   scanf("%d%d%d",&n,&m,&k);
   for(i=0;i<n;i++)
   {
       scanf("%d",&a[i]);
       p[i]=v[a[i]].size();//p【】记录在vector【a【i】】里的下标
       v[a[i]].push_back(i);//把当前数的下标压进去
   }
   int low,high,mid,num;
   int max=0;
   for(i=0;i<n;i++)//二分查找
   {
       low=p[i];
       high=v[a[i]].size()-1;
       while(low<=high)
       {
           mid=(low+high)/2;
           int t=v[a[i]][mid]-i-(mid-p[i]);//t是相同的元素间不同元素的个数
           // t=在原数组(a【】)中 两个相同元素之间的差 - 在vector中两个相同素数间 相同的元素
           if(t<=k)
           {
               num=mid-p[i]+1;
               if(num>max)
                   max=num;
               low=mid+1;
           }
           else
               high=mid-1;
       }
   }
   printf("%d\n",max);
   return 0;
}


别忘了相同元素间的除了不同元素还有相同元素,所以数组的序号相减后要减去向量的序号之差才是真正的这两个相同元素之间要删除的元素。

0 0