洛谷P3069 [USACO13JAN]牛的阵容Cow Lineup(尺取法)
2024-08-28 02:14:54
思路
考虑比较朴素的解法,枚举每个长度为\(k+1\)的区间,然后统计区间中出现次数最多的颜色。这样的话复杂度为\(O(n*k)\)的,显然不行。
观察到统计每个区间中出现次数最多的颜色中,可以只用看每种颜色在区间中出现的最后一个位置,这样的话只需要我们开个桶统计一下数量就行。
所以就类似于尺取那样,维护颜色种类不超过\(k+1\)的区间,对于每次新加进来的值令其\(cnt++\),并且维护ans。当颜色种类超过\(k+1\)时,就减去区间前面的值,因为它们与后面的颜色不可能再连在一起了。
因为每个位置都会被指针扫到最多两次,所以复杂度是\(O(n)\)的。
直接看代码好了,注意要离散化一下:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N = 1e5 + 5;
int n, k;
int a[N], b[N];
int cnt[N];
int main() {
ios::sync_with_stdio(false); cin.tie(0);
cin >> n >> k;
for(int i = 1; i <= n; i++) cin >> a[i], b[i] = a[i] ;
sort(b + 1, b + n + 1);
int D = unique(b + 1, b + n + 1) - b - 1;
for(int i = 1; i <= n; i++) a[i] = lower_bound(b + 1, b + n + 1, a[i]) - b;
int num = 0, ans = 1;
for(int l = 1, r = 0; r <= n;) {
r++;
if(cnt[a[r]]++ == 0) num++;
while(num > k + 1) {
cnt[a[l++]]--;
if(!cnt[a[l - 1]]) num--;
}
ans = max(ans, cnt[a[r]]) ;
}
cout << ans;
return 0;
}
最新文章
- Discuz!用户注册,登陆,生成帖子功能实现
- CLR via C#(04)- 本是同根生
- webservice的Axis2入门教程java版
- SAE java应用读写文件(TmpFS和Storage)-----绝世好代码
- sublime text3 本地化
- idea 14 svn安装
- java functional syntax overview
- Ubuntu 误改/etc/sudoers 文件权限
- SpringMVC——从HelloWorld
- HDU 2018 undefined
- MySQL timestamp NOT NULL插入NULL的问题
- 小甲鱼OD学习第7讲
- PHP 【一】
- 服务器资源监控插件(jmeter)
- navLI鼠标滑上显示下拉导航
- 强化学习4-时序差分TD
- asp.net query string 及 form data 遇到的编码问题
- 021.Zabbix的邮件告警-01
- appium+python+unittest 测试用例的几种加载执行方式
- 怎样通过terminal得到AWS EC2 instance的ip