P5093 [USACO04OPEN]The Cow Lineup 奶牛序列

Posted mysh

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P5093 [USACO04OPEN]The Cow Lineup 奶牛序列相关的知识,希望对你有一定的参考价值。

题目描述

约翰的 N ( 1≤N≤100000 )只奶牛站成了一列。每只奶牛都写有一个号牌,表示她的品种,号牌上的号码在 1…K ( 1≤K≤10000)范围内。

比如有这样一个队列:1,5,3,2,5,3,4,4,2,5,1,2,3

根据约翰敏锐的数学神经,他发现一些子序列在这个队列里出现,比如"3,4,1,3",而另一些没有。子序列的各项之间穿插有其他数,也可认为这个子序列存在。现在,他想找出一个最短的子序列,使之不在奶牛序列里出现。达个子序列的长度是多少呢?

输入格式

第1行输入两个整数 N K ,接下来 N 行输入奶牛序列.

输出格式

输出一行,最短的不出现子序列的长度。

输入输出样例

输入 #1
14 5
1
5
3
2
5
1
3
4
4
2
5
1
2
3
输出 #1
3

说明/提示

样例解释:

所有长度为1和2的可能的子序列都出现了,但长度为3的子序列"2,2,4"却没有出现。

思路

考虑将奶牛分组。

1...k中的每个数字都出现的连续一段分成一组。

例如,样例分成[1,5,3,2,5,1,3,4],[4,2,5,1,2,3]两组。

容易发现,每一组的最后一个数字一定是在这一组中最后出现且只出现一次

所以!把每个组的最后一个数字取出来,然后剩下的组不成一组的,必然存在没有出现的数字,将其取出。

所以答案是组数+1

代码

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N=10010;

int a[N];
int n,k,x;
int ans,tot;

int main () {
	scanf("%d%d",&n,&k);
	for(int i=1; i<=n; i++) {
		scanf("%d",&x);
		if(!a[x]) {
			a[x]=1;
			tot++;
		}
		if(tot==k) {
			memset(a,0,sizeof(a));
			tot=0;
			ans++;
		}
	}
	printf("%d
",ans+1);
	return 0;
}

 

以上是关于P5093 [USACO04OPEN]The Cow Lineup 奶牛序列的主要内容,如果未能解决你的问题,请参考以下文章

BZOJ1665 Usaco2006 Open The Climbing Wall

BZOJ4101[Usaco2015 Open]Trapped in the Haybales Silver 二分

洛谷P3145 [USACO16OPEN]分割田地Splitting the Field

[USACO16OPEN]关闭农场Closing the Farm(洛谷 3144)

[USACO16OPEN]关闭农场Closing the Farm_Silver

[BZOJ] 1621: [Usaco2008 Open]Roads Around The Farm分岔路口