思维题。

显然考虑爆搜。然后考虑n^2能做不能。

容易想到枚举中间的数字mid 然后往mid两边加数字 使其整个集合权值最大。

这里有一个比较显然的贪心就不再赘述了。

可以发现这样做对于集合是奇数的时候可以遍历到所有最优的情况。这一步复杂度为n^2.

但是值得注意的是 如果集合为偶数的时候怎么解决 暴力枚举两个数字在中间这复杂度已经是n^3的了 再向两边拓展复杂度会更高。

有多种解决方法:1 尝试证明偶数的序列一定没有奇数的优。2 尝试证明两个数字只有是相邻的时候比其他不相邻的更优 3 使用固定左端点 移动右端点的方法 这样可以做到n^2.

使用方法3过于无脑 我考试的时候 脑子不太好使没想到1这个性质 只是把2证明了一下。还是很容易证明的。

至此得到了一个n^2的做法。

考虑正解。经过不断的推式子 可以发现这类似于分数规划问题。可以先二分答案。

然后就是对于每一个中点直接求出最大的序列的值是否满足二分的答案即可。

可以发现这样做是n^2logn的。

不过考虑一个端点不断的向右移动可以发现每次最多加入两个数字 所以利用这个东西可以扫一遍得到答案。

不过考试sb了 外面套了一个set简化代码 其实是把代码和时间复杂度都复杂化了 直接记录两个端点就行了。

对于偶数也是如此。时间复杂度nlog.(不过考试的时候套了一个set复杂度nlog^2.

对于题解:容易证明奇数比偶数更优 自证不难。

然后考虑枚举中位数。显然选取的个数与价值是严格单峰的所以三分一下就行了。

code:set代码。

const int MAXN=200010;
int n,top,maxx;db ans;
int a[MAXN],b[MAXN],vis[MAXN];
multiset<int>s1,s2;
multiset<int>::iterator it1,it2;
inline void dfs(int x)
{
if(x==n+1)
{
top=0;db cnt=0;
rep(1,n,i)if(vis[i])b[++top]=a[i],cnt+=a[i];
cnt=cnt/top;
if(top&1)cnt-=b[(top>>1)+1];
else cnt-=(1.0*b[(top>>1)]+1.0*b[(top>>1)+1])/2;
ans=max(ans,cnt);
return;
}
vis[x]=1;
dfs(x+1);
vis[x]=0;
dfs(x+1);
}
inline int check(db x)
{
db sum1=0,sum2=x;
int L=0,R=n;ll cnt=0;
s1.clear();s2.clear();
rep(2,n,i)//处理单个中位数.
{
L=L==i-2?i-1:L;
if(s1.size())//更改
{
it1=s1.begin();
sum1-=*it1;
s1.erase(it1);
sum1+=a[i-1];
s1.insert(a[i-1]);
++L;
}
if(a[L]+a[R]-x-x-a[i]-a[i]>=0&&R>i&&L)//插入
{
s1.insert(a[L]);sum2+=x+x;
s2.insert(a[R]);
sum1+=a[L];sum1+=a[R];cnt+=2;
--R;--L;
}
if(R+1==i)
{
it1=s1.begin();
sum1-=*it1;
it2=s2.begin();
sum1-=*it2;
s1.erase(it1);
s2.erase(it2);
++R;++L;cnt-=2;
sum2=sum2-x-x;
}
while(s1.size())
{
it1=s1.begin();
it2=s2.begin();
if(*it1+*it2-x-x-a[i]-a[i]<0)
{
sum1-=*it1;
sum1-=*it2;cnt-=2;
s1.erase(it1);
s2.erase(it2);
sum2=sum2-x-x;
++R;++L;
}
else break;
}
if(sum1-sum2-cnt*a[i]>=0)return 1;
}
return 0;
}
int main()
{
freopen("subset.in","r",stdin);
freopen("subset.out","w",stdout);
get(n);
rep(1,n,i)get(a[i]),maxx=max(maxx,a[i]);
sort(a+1,a+1+n);
if(n<=20)
{
dfs(1);
printf("%.5lf\n",ans);
return 0;
ans=0;
}
if(n<=2000)
{
rep(1,n,i)//枚举中位数的位置
{
db sum=0;int cnt=1;
for(int j=1;j<=min(i-1,n-i);++j)
{
cnt+=2;
sum+=a[i-j]+a[n-j+1]-a[i]-a[i];
ans=max(ans,sum/cnt);
}
}
printf("%.5lf\n",ans);
return 0;
}
db l=0,r=maxx;
while(l+EPS<r)
{
db mid=(l+r)/2;
if(check(mid))l=mid;
else r=mid;
}
printf("%.5lf\n",r);
return 0;
}

4.23 子集 分数规划 二分 贪心 set 单峰函数 三分的更多相关文章

  1. 51nod——1086、1257背包问题V2(多重背包二进制拆分转01) V3(分数规划+二分贪心)

    V3其实和dp关系不大,思想挂标题上了,丑陋的代码不想放了.

  2. hdu6070(分数规划/二分+线段树区间更新,区间最值)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=6070 题意: 给出一个题目提交序列, 从中选出一个正确率最小的子串. 选中的子串中每个题目当且仅当最 ...

  3. BZOJ 1758 / Luogu P4292 [WC2010]重建计划 (分数规划(二分/迭代) + 长链剖分/点分治)

    题意 自己看. 分析 求这个平均值的最大值就是分数规划,二分一下就变成了求一条长度在[L,R]内路径的权值和最大.有淀粉质的做法但是我没写,感觉常数会很大.这道题可以用长链剖分做. 先对树长链剖分. ...

  4. POJ2728 最小比率生成树/0-1分数规划/二分/迭代(迭代不会)

    用01分数规划 + prime + 二分 竟然2950MS惊险的过了QAQ 前提是在TLE了好几次下过的 = = 题目意思:有n个村庄,村庄在不同坐标和海拔,现在要对所有村庄供水,只要两个村庄之间有一 ...

  5. POJ - 3111 K Best 0-1分数规划 二分

    K Best Time Limit: 8000MS   Memory Limit: 65536K Total Submissions: 12812   Accepted: 3290 Case Time ...

  6. 51nod 1257 01分数规划/二分

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1257 1257 背包问题 V3 基准时间限制:3 秒 空间限制:1310 ...

  7. 2018年东北农业大学春季校赛 I wyh的物品【01分数规划/二分】

    链接:https://www.nowcoder.com/acm/contest/93/I来源:牛客网 题目描述 wyh学长现在手里有n个物品,这n个物品的重量和价值都告诉你,然后现在让你从中选取k个, ...

  8. 【Luogu】P3705新生舞会(费用流+分数规划+二分答案)

    题目链接 本来以为自己可以做出来,结果……打脸了 (貌似来wc立了好几个flag了,都没竖起来) 不过乱蒙能蒙出一个叫“分数规划”的东西的式子还是很开心的 观察$C=\frac{a_{1}+a_{2} ...

  9. bzoj 4753: [Jsoi2016]最佳团体【01分数规划+二分+树上背包】

    01分数规划,二分答案然后把判别式变成Σp[i]-Σs[i]*mid>=0,然后树上背包判断,设f[i][j]为在i点子树里选j个的最大收益,随便背包一下就好 最丧病的是神卡常--转移的时候要另 ...

随机推荐

  1. P1330 封锁阳光大学——深度优先搜索DFS

    P1330 封锁阳光大学 题目描述 曹是一只爱刷街的老曹,暑假期间,他每天都欢快地在阳光大学的校园里刷街.河蟹看到欢快的曹,感到不爽.河蟹决定封锁阳光大学,不让曹刷街. 阳光大学的校园是一张由 \(n ...

  2. 13.Camera摄像机常用属性

    选中Main Camera相机,在最右侧的Inspector面板可以看到有Camera组件,该组件下有一些摄像机常用的属性. 1.Clear Flags属性 SkyBox:天空盒(默认效果,场景会有天 ...

  3. 3.Unity3d物体操作常用按键

    新建一个cube物体.在unity3d界面左上角可以看到红色下划线的五个图标(下面用图标1到5数字表示),分别对应不同功能,这些功能操作物体很常用.下面用cube物体的操作来演示这几个功能. 1.按Q ...

  4. ES6入门(二)

    目录 ES6入门(二) es6之解构赋值 数组的解构赋值 对象的解构赋值 字符串的解构赋值 数值和布尔值的解构赋值 函数参数的解构赋值 圆括号问题 ES6入门(二) es6之解构赋值 数组的解构赋值 ...

  5. 装机预备技能,Linux系统简介,安装Linux系统,Linux基本操作-云计算学习(2)

    装机预备技能 问题 要求安装一台可用的KVM服务器: RHEL与CentOS系统有什么关联? Linux系统中第三块SCSI硬盘如何表示? 步骤 实现此案例需要按照如下步骤进行. 步骤一:RHEL系统 ...

  6. MCU 51-3定时器

    51定时/计数器简介 51单片机有2个16位定时器/计数器:定时器0(T0为P3.4)和定时器1(T1为P3.5).这里所说的16位是指定时/计数器内部分别有16位的计数寄存器. 当工作在定时模式时, ...

  7. python numpy indexerror: too many indices for array

    import numpy as np #data 原来数组 #arr_1 新数组 #将data的第一列赋值给arr_1的第一列 arr_1 = np.array((data.shape[0],5)) ...

  8. shell专题(十):Shell工具(重点)

    10.1 cut cut的工作就是“剪”,具体的说就是在文件中负责剪切数据用的.cut 命令从文件的每一行剪切字节.字符和字段并将这些字节.字符和字段输出. 1.基本用法 cut [选项参数]  fi ...

  9. Python并发编程06 /阻塞、异步调用/同步调用、异步回调函数、线程queue、事件event、协程

    Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件event.协程 目录 Python并发编程06 /阻塞.异步调用/同步调用.异步回调函数.线程queue.事件 ...

  10. C#程序安装为windows服务的方式

    项目开发中,需要将采集程序以windows服务的形式进行部署,可分为定时采集程序以及监控采集程序. 1.定时采集程序 采用Quartz.net框架实现定时任务,针对该种情形,可采用批处理文件的形式进行 ...