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 行输入奶牛序列.
输出格式
输出一行,最短的不出现子序列的长度。
输入输出样例
14 5 1 5 3 2 5 1 3 4 4 2 5 1 2 3
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)