CF 1486D & ABC 236E (二分 0/1分数规划)

image

  • 直接二分答案中位数x。
  • check: 让小于x的为-1,大于等于的为1,这样最大中位数大于等于x的话,就是能找到长度至少为k的区间使得大于0.
#include<bits/stdc++.h>
using namespace std;
#define IOS ios::sync_with_stdio(false) ,cin.tie(0), cout.tie(0);
//#pragma GCC optimize(3,"Ofast","inline")
#define ll long long
const int N = 2e5 + 5;
const int M = 1e6 + 5;
const ll LNF = 0x3f3f3f3f3f3f3f3f;
const int mod = 1e9 + 7;
int a[N], b[N], n, pre[N], k;
bool check(int x) {
    for (int i = 1; i <= n; ++ i) {
        if(a[i] >= x) b[i] = 1; else b[i] = -1;
        pre[i] = pre[i - 1] + b[i];
    }
    int mn = 0x3f3f3f3f, mx = -0x3f3f3f3f;
    for(int i = k; i <= n; ++ i) {
        mn = min(pre[i - k], mn);
        mx = max(mx, pre[i] - mn);
    }
    return mx > 0; // > 还是 >= 根据题目具体分析
}
int main() {
    IOS
    cin >> n >> k;
    for (int i = 1; i <= n; ++ i) cin >> a[i];
    int l = 1, r = n;
    while(l < r) {
        int mid = l + r + 1 >> 1;
        if(check(mid)) l = mid;
        else r = mid - 1;
    }
    cout << l << endl;
    return 0;
}

image

  • 也是直接二分答案x, 让小于x的为-1,大于等于的为1
  • check: dp[i][0/1] 表示走到2* i个数字,的最大值,看是否大于0
posted @ 2022-03-26 15:00  qingyanng  阅读(41)  评论(0编辑  收藏  举报