1. 程式人生 > >2017-9-3 校內模擬T2取數win

2017-9-3 校內模擬T2取數win

turn 三分搜索 can 最大 main 序列 color 中位數 pre

題意:給你一個序列,叫你找一個子序列,使得這個子序列的平均數減去中位數最大。

思路:題面直接說是單峰函數,我也沒多想(根本沒看懂),現在看來就是排序+三分搜索啦。

代碼:(特地去學了下三分。。):

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
int n;
long long lefts,rights,lm,mr;
int num[200100],presum[200100];
double ansx,anss,ans,hh=-1;
double df(long
long w,long long l){ long long k=presum[w]-presum[w-l-1]+presum[n]-presum[n-l]; return (double)k/(double)(2*l+1)-(double)num[w]; } int main(){ //freopen("win.in","r",stdin); //freopen("win.out","w",stdout); scanf("%d",&n); if(n<3){ printf("0.00\n"); return 0; }
for (int i=1;i<=n;i++) scanf("%d",&num[i]); presum[0]=1; sort(num+1,num+n+1); for (int i=1;i<=n;i++) presum[i]=presum[i-1]+num[i]; for (int i=1;i<=n;i++){ lefts=0; rights=min(n-1,i-1); while(lefts<rights){ lm=(rights-lefts)/3
+lefts; mr=rights-(rights-lefts)/3; ansx=df(i,lm);anss=df(i,mr); if(ansx>anss) rights=mr-1; else lefts=lm+1; } ans=df(i,lefts); if(ans>hh) hh=ans; } printf("%.2lf\n",hh); return 0; }

2017-9-3 校內模擬T2取數win