1. 程式人生 > 資訊 >拆下後秒變無線滑鼠,蘋果申請可拆卸式 MacBook 鍵盤專利:外出辦公不必單獨攜帶滑鼠

拆下後秒變無線滑鼠,蘋果申請可拆卸式 MacBook 鍵盤專利:外出辦公不必單獨攜帶滑鼠

ABC 236 E - Average and Median

題目連結
https://atcoder.jp/contests/abc236/tasks/abc236_e

解析

  • 想到了dp以及狀態表示,但是沒想出來怎麼狀態轉移,主要沒想到是用dp來判斷mid行不行的,總體框架來看是個二分答案的題
  • 本題對於中位數和平均數的處理特別經典,可以學習
  • 題解就不寫了,參考這篇部落格吧
    https://blog.csdn.net/Mr_dimple/article/details/122679274

Ac程式碼

點選檢視程式碼
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
 
using namespace std;
 
const int N = 1e5 + 10;
 
int n;
double f[N][2];
double b[N];
int a[N];
 
bool check1(double mid){
    for(int i = 1; i <= n; i ++) b[i] = a[i] - mid;
 
    for(int i = 1; i <= n; i ++){
        f[i][0] = f[i - 1][1];
        f[i][1] = max(f[i - 1][0], f[i - 1][1]) + b[i];
    }
    return max(f[n][0], f[n][1]) > 0;
}
 
bool check2(int mid){
    for(int i = 1; i <= n; i ++) b[i] = a[i] >= mid ? 1 : -1;
 
    for(int i = 1; i <= n; i ++){
        f[i][0] = f[i - 1][1];
        f[i][1] = max(f[i - 1][1], f[i - 1][0]) + b[i];
    }
    return max(f[n][0], f[n][1]) > 0;
}
 
int main()
{
    scanf("%d", &n);
    int maxa = 0;
    for(int i = 1; i <= n; i ++) scanf("%d", &a[i]), maxa = max(maxa, a[i]);
 
    //求最大平均數
    double ll = 0, rr = maxa;
    while(rr - ll > 1e-4){
        double mid = (ll + rr) / 2;
        if(check1(mid)) ll = mid;
        else rr = mid;
    }
    printf("%.10lf\n", ll);
 
    //求最大中位數
    int l = 0, r = 1e9;
    while (l < r)
    {
        int mid = l + r + 1 >> 1;
        if (check2(mid)) l = mid;
        else r = mid - 1;
    }
    printf("%d\n", l);
 
    return 0;
}