洛谷 P3029 [USACO11NOV]【牛的阵容Cow Lineup】

描述

  Cow Lineup [Brian Dean and Daniel Dara, 2012] Farmer John's N cows 
  (1 <= N <= 100,000) are lined up in a row. Each cow is identified
   by an integer "breed ID" in the range 0...1,000,000,000; the breed 
  ID of the ith cow in the lineup is B(i). Multiple cows can share the 
  same breed ID. FJ thinks that his line of cows will look much more 
  impressive if there is a large contiguous block of cows that all have 
  the same breed ID. In order to create such a block, FJ chooses up to K 
  breed IDs and removes from his lineup all the cows having those IDs. 
  Please help FJ figure out the length of the largest consecutive block 
  of cows with the same breed ID that he can create by doing this. 

  有N头牛(1 <= N <= 100,000) 排成一列。每头牛有一个标号,范围在0到1000000000,
  第 i 头牛的编号为B(i)。多头牛可以共享一个编号。John想,如果前后相邻的多头牛
  能有相同的编号,将会更好。为了使前后相连且编号相同的牛的数量尽可能多,
  John将选择 K 个编号,然后移除编号与这K个编号相同的牛。请帮忙选择编号。

输入输出格式

输入

  第1行:N和K 
  第2至N+1行:Line i+1 第i头牛的编号 B(i)

输出

  连续的编号相同的牛的最大总数。

输入输出样例

输入样例1

9 1 
2 
7 
3 
7 
7 
3 
7 
5 
7 

输出样例1

4

解题思路

  老样子,尺取法,维护一个区间,定义一个左端点和右端点,以及区间内每个数的个数。右端点不断向右移,每次移的时候,都记录右端点代表的数的个数,并且取最优值,当种类(p)=k+2时,左端点就该向右移了,直到区间内的种类小于等于k+1。最后输出即可。还有,本题的编号太大,所以我们采用离散化。

题解

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 int n,k,ans=0;
 4 map<long long,int> sj;//离散化 
 5 int cow[100001];//牛的编号 
 6 int in[100001];//区间内的每个编号的数量 
 7 long long read()//快读,这个是真的有用,能节省很多时间 
 8 {
 9     long long x=0,f=1;
10     char ch=getchar();
11     while(ch<'0'||ch>'9'){
12         if(ch=='-')
13             f=-1;
14         ch=getchar();
15     }
16     while(ch>='0'&&ch<='9'){
17         x=(x<<1)+(x<<3)+(ch^48);
18         ch=getchar();
19     }
20     return x*f;
21 }
22 int main()
23 {    
24     cin>>n>>k;
25     int sum=0;
26     for(int i=1;i<=n;i++)
27     {
28         long long s;
29         s=read();//快读 
30         if(sj[s]==0)
31         {
32             sum++;//离散化,如果有没被记录就给它分配新的离散化值 
33             sj[s]=sum;
34             cow[i]=sum;
35         }
36         else
37         {
38             cow[i]=sj[s];
39         }
40     }
41     int l=1,r=0,p=0;//左端点,右端点,区间内种类 
42     while(r<n)
43     {
44         r++;//向右移 
45         if(in[cow[r]]==0)p++;//没有就种类+1 
46         in[cow[r]]++;//数量+1 
47         while(p==k+2)种类超了 
48         {
49             in[cow[l]]--;//左端点的数量-1 
50             if(in[cow[l]]==0)p--;//没有了种类-1 
51             l++;//左端点向右移 
52         }
53         ans=max(ans,in[cow[r]]);//取最优值 
54     }
55     cout<<ans;//输出 
56     return 0;
57 }
原文地址:https://www.cnblogs.com/hualian/p/11183994.html