ubuntu20.04下lxc啟動openwrt
阿新 • • 發佈:2022-03-16
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; }