ZOJ 3790 Consecutive Blocks

来源:互联网 发布:tk顶级域名注册官网 编辑:程序博客网 时间:2024/05/20 02:54

Time Limit: 2 Seconds      Memory Limit: 65536 KB

There are N (1 ≤ N ≤ 105) colored blocks (numbered 1 to N from left to right) which are lined up in a row. And the i-th block's color is Ci (1 ≤ Ci ≤ 109). Now you can remove at most K(0 ≤ K ≤ N) blocks, then rearrange the blocks by their index from left to right. Please figure out the length of the largest consecutive blocks with the same color in the new blocks created by doing this.

For example, one sequence is {1 1 1 2 2 3 2 2} and K=1. We can remove the 6-th block, then we will get sequence {1 1 1 2 2 2 2}. The length of the largest consecutive blocks with the same color is 4.

Input

Input will consist of multiple test cases and each case will consist of two lines. For each test case the program has to read the integers N and K, separated by a blank, from the first line. The color of the blocks will be given in the second line of the test case, separated by a blank. The i-th integer means Ci.

Output

Please output the corresponding length of the largest consecutive blocks, one line for one case.

Sample Input

8 11 1 1 2 2 3 2 2

Sample Output

4


题意:给你n个数字组成的有序数列,你可以选择性地最多删除k个数,问删完之后的数列最多有多少个相同的数连在一起。


最开始想着用表存,后来发现其实不需要,直接用一个结构体记录val(值)和num(在原数组中的位置),然后根据val sort一下,从第一个开始判一遍就好了。


#include <stdio.h>#include <string.h>#include <iostream>#include <math.h>#include <algorithm>#include <vector>#include <map>#define PI acos(-1.0)#define M 1000005  //10^6#define eps 1e-8#define LL long long#define moo 1000000007#define INF -999999999#define LL long longusing namespace std;struct ttt{    int num;    int val;}tt[M];bool cmp(ttt a,ttt b){    if(a.val!=b.val)        return a.val>b.val;    if(a.val==b.val)        return a.num<b.num;}int main(){    int m,n;    while(scanf("%d%d",&m,&n)!=EOF)    {        int num=0;        for(int i=1;i<=m;i++)        {            scanf("%d",&tt[i].val);            tt[i].num=i;        }        sort(tt+1,tt+m+1,cmp);        int ans=1;        int now=n;   //记录剩余可删的数        int pick;    //记录当前判断的val值        int puck=1;  //记录当前连续数值        pick=tt[1].val;        int head=1;  //记录当前连续段是从哪个开始的(其实这个可以去掉,用i-pick代替,这里加上是为了方便)        for(int i=2;i<=m;i++)        {            if(tt[i].val==pick)   //当新入队的数跟前面的一样,就判断以它为结尾最多能连多少个            {                if(tt[i].num-tt[i-1].num-1<=now)                {                    puck++;                    ans=max(ans,puck);                    now=now-(tt[i].num-tt[i-1].num-1);                }                else                {                    int flag=0;                    for(head;head<=i-1;head++)                    {                        puck--;                        now=now+(tt[head+1].num-tt[head].num-1);                        if(now>=tt[i].num-tt[i-1].num-1)                        {                            flag=1;                            break;                        }                    }                    if(flag==0)                    {                        now=n;                        puck=1;                        head=i;                    }                    else                    {                        puck++;                        now=now-(tt[i].num-tt[i-1].num-1);                        head++;                    }                    ans=max(ans,puck);                }            }            else    //新入队的数跟前面的不一样,说明前面一个数已经判完了,于是所有参数初始化            {                now=n;                pick=tt[i].val;                head=i;                puck=1;            }        }        cout<<ans<<endl;    }}/*10 31 2 3 4 1 6 7 1 9 110 32 1 3 1 4 5 6 9 1 1ans32*/


0 0
原创粉丝点击