0
点赞
收藏
分享

微信扫一扫

CodeForces Good Bye 2021: 2022 is NEAR D – Keep the Average High

岛上码农 2022-04-21 阅读 124
算法

题意

给定 a 1 , a 2 , ⋯   , a n a_1, a_2, \cdots, a_n a1,a2,,an n n n 个数,以及一个整数 x x x

要在数组中选择尽量多的数,使得原数组任意一个长度大于 1 的子数组满足以下条件之一

  • 至少有一个元素没有被选择
  • a l , a l + 1 , ⋯   , a r ≥ x ∗ ( r − l + 1 ) a_l, a_{l+1}, \cdots , a_r \geq x * (r-l+1) al,al+1,,arx(rl+1)

思路

观察条件 a l , a l + 1 , ⋯   , a r ≥ x ∗ ( r − l + 1 ) a_l, a_{l+1}, \cdots , a_r \geq x * (r-l+1) al,al+1,,arx(rl+1) ,也就是说选中的元素平均值要大于 x x x 。大于等于 x x x 的元素对平均值有正的贡献,小于 x x x 的元素对平均值有负的贡献。不妨记大于等于 x x x 的元素为A,小于 x x x 的元素为B。由于相邻两个元素的平均值不能小于 x x x ,所以不可能存在BB相连的情况,B只可能单独存在或依附于A。只需要考虑B、AB、BA、BAB这四种形式即可。

从前往后枚举每一个元素,对于第 i i i 个元素贪心地进行选择:

如果第 i − 1 i−1 i1个元素未选,则当前为元素为孤立的,可以选择。
如果第 i − 1 i−1 i1个元素已选,第 i − 2 i−2 i2个元素未选,则需要考虑当前元素与前一个元素的平均值进行选择。
如果第 i − 1 i−1 i1个元素与第 i − 2 i−2 i2 个元素均已选,则需要考虑这三个元素的平均值与后两个元素的平均值进行选择。

代码

#include <iostream>
#include <vector>
#include <cstring>
using namespace std;
 
const int maxn = 1e5+10;
 
int num[maxn];
int dp[maxn];
 
signed main() {
 
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#endif

 
    int t; cin >> t;
    while(t--){
        memset(num, 0, sizeof num);
        memset(dp, 0, sizeof dp);
 
        int n; cin >> n;
        for(int i = 1 ; i<=n; i++){
            cin >> num[i];
        }
 
        int x; cin >> x;
 
        int ans = 0;
        dp[1] = 1;
        ans ++;
        for(int i = 2; i<=n; i++){
            if(!dp[i-1]) dp[i] = 1, ans++;
            else if(dp[i-1] && !dp[i-2]){
                if(num[i] + num[i-1] >= 2*x) dp[i] = 1, ans++;
            }else if(dp[i-1] && dp[i-2]){
                if(num[i] + num[i-1] + num[i-2] >= 3*x && num[i] + num[i-1] >= 2*x) dp[i] = 1, ans++;
            }
        }
 
        cout << ans << endl;
 
    }
 
    return 0;
}
举报

相关推荐

0 条评论