2022-01-27 16:22阅读: 154评论: 0推荐: 0

Atcoder Beginner Contest 236 E Average and Median

E. Average and Median

题目大意

给定一个数组x,从中选出一些数字,要求俩俩相邻的数中必选一个,最大化平均值和中位数。

中位数的定义为第n2小的数。

解题思路

刚开始想着各种贪心DP都觉得不对,直接整平均数不一定有最优子结构。事后发现可以二分答案判断。

就是二分平均数a,如果对于选出来的数xi(xia)0,那么这个平均数就可以达到。

而判断能否选出这些数就是个简单dp,令gi=xia,记f[i][0/1]表示第 i个数选或不选的最大值,f[i][0]=f[i1][1],f[i][1]=min(f[i1][0],f[i1][1])+gi,最后看max(f[n][0],f[n][1])是否大于等于0即可。

中位数的话也一样,即如果有一半的数小于等于中位数。即令gi=[xi>=a]21,同样用上述 f,最后看 max(f[n][0],f[n][1])是否大于0即可。

神奇的代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const double eps = 1e-5;
int main(void) {
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
int n;
cin >> n;
vector<int> qwq;
LL sum = 0;
for(int i = 1; i <= n; ++ i){
LL x;
cin >> x;
qwq.push_back(x);
sum += x;
}
double l = 0, r = 1e9 + 7;
auto check = [qwq](double x){
vector<vector<double>> dp(qwq.size(), vector<double>(2, 0));
dp[0][1] = qwq[0] - x;
for(int i = 1; i < qwq.size(); ++ i){
dp[i][0] = dp[i - 1][1];
dp[i][1] = max(dp[i - 1][0], dp[i - 1][1]) + qwq[i] - x;
}
return dp.back()[0] >= 0 || dp.back()[1] >= 0;
};
while(l + eps < r){
double mid = (l + r) / 2;
if (check(mid))
l = mid;
else
r = mid;
}
cout << fixed << setprecision(8) << l << endl;
auto check2 = [qwq](int x){
vector<vector<int>> dp(qwq.size(), vector<int>(2, 0));
dp[0][1] = (qwq[0] >= x) * 2 - 1;
for(int i = 1; i < qwq.size(); ++ i){
dp[i][0] = dp[i - 1][1];
dp[i][1] = max(dp[i - 1][0], dp[i - 1][1]) + (qwq[i] >= x) * 2 - 1;
}
return dp.back()[0] > 0 || dp.back()[1] > 0;
};
int ll = 0, rr = 1e9 + 7;
while(ll + 1 < rr){
int mid = (ll + rr) >> 1;
if (check2(mid))
ll = mid;
else
rr = mid;
}
cout << ll << endl;
return 0;
}


本文作者:~Lanly~

本文链接:https://www.cnblogs.com/Lanly/p/15850248.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   ~Lanly~  阅读(154)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.