题目链接:
https://codeforces.com/problemset/problem/1616/D
题目大意:
给定一个长度为 \(n\) 的序列和一个 \(x\),选择序列中的一些元素,使序列中所有子区间 \(a_l\),\(a_{l + 1}\),...,\(a_r\) 满足 \(\sum_{i = l}^r\) >= x * (r - l + 1) 或者其中一个及以上的元素未被选择这两个条件,求能选择的元素最多是多少。
思路:
\(\sum_{i = l}^r\) >= x * (r - l + 1) 即 \(l\) 到 \(r\) 的区间内所有的元素的平均数要大于等于 \(x\),于是可以让序列中所有的元素先减去 \(x\),那么该条件就转化为平均数非负就可以了。
一个序列所有子区间都大于 0 的话,只需要所有长度为 2 或 3 的子区间非负就可以了。而要使选择的元素最多,先假设选择了全部的数字,再先考虑非负,若有负,则少选一个数。
代码:
#include <bits/stdc++.h>
using namespace std;
int T, n, ans;
void solve(){
scanf("%d", &n);
int ans = n, x;
vector <int> a(n);
for (int i = 0; i < n; i++)
scanf("%d", &a[i]);
scanf("%d", &x);
for (int i = 0; i < n; i++)
a[i] -= x;
int p = 0;
for (int i = 1; i < n; i++){
bool f = false;
if (i >= 1 && i - p >= 1 && a[i] + a[i - 1] < 0) f = true;
if (i >= 2 && i - p >= 2 && a[i] + a[i - 1] + a[i - 2] < 0) f = true;
if (f){
ans--;
p = i + 1;
}
}
cout << ans << "\n";
}
int main(){
cin >> T;
while (T--)
solve();
return 0;
}