BZOJ 4030: [HEOI2015]小L的白日梦
4030: [HEOI2015]小L的白日梦
Time Limit: 10 Sec Memory Limit: 256 MB
Submit: 172 Solved: 39
[Submit][Status][Discuss]
Description
在某一天,你有了一个女性朋友。
Input
第一行有一个非负整数t,表示一共有t组数据。
Output
一共t行,对于每组数据输出使她感到失落的最小期望次数,四舍五入保留6位小数。
Sample Input
1 2
0/1 3
1 2
1/1 3
1 2
1/2 3
Sample Output
0.000000
0.250000
【样例说明】
考虑第三组数据,因为只有一个项目所以只好每天都安排这个。
在第一天之前她总是不高兴的,一共有:
第一天不高兴,第二天也不高兴、
第一天高兴,第二天不高兴、
第一天不高兴,第二天高兴、
第一天不高兴,第二天也不高兴,
这四种情况,又因为每天的项目让她高兴或者是不高兴的概率都是0.5,因此这四种情况是等概率发生的。
只有在第二种情况下,她会感到失落一次。
因此答案是(1*1+0*3)/4=0.25.
HINT
对于100%的数据,n<=105,k<=109,数据组数不会太多,大概不超过10组,数据保证分数有意义并且∑c[i]>=k。
Source
这种网上没有题解的题,必须要写一发骗骗访问量哈~~~
我上午做这道题的时候,网上没有专门的题解,只有jiry前辈的一篇HEOI2015系列题解可做参考,所以我就无耻地抄代码啦~~~
先转一下jiry的题解内容——
【D2T1】小L的白日梦
这题我在网上找不到题解..但是为了访问量我也是只好硬上了...我的算法建立在以下假设之上:
1.一定存在最优解每一天不高兴的概率是单调不增的。
2.一定存在最优解它选取的项目是所有项目按照不高兴的概率排序后的前缀一段加上后缀一段。
3.每一次选取的项目种类只有三种可能的情况:选了1个,全部选完,其他。且处于第三种状态的至多一个。
不要问我是怎么知道这三个假设的..我连最基本的假设1都不会证明..这些全部都是在各种暴力求证之后得到了..这A的实在是6的不行..
知道了这些假设就很简单了..假设第三种状态的是取在后缀中的,那么枚举选取前缀最右端的位置,后缀最左端的位置单调不增,扫一下就好了,反过来也是一样。
我看了看这三个假设,如果是正确的话那么jiry的做法确实很棒棒,但是我只能证明第一个,好菜啊。下午Monster__Yi来嘲讽我了,“这么水的题,你都不会证明?还考什么NOI,HEOI你就可以滚粗了!” 唔唔唔,宝宝心里苦啊……
然后在小天天(Monster_Yi)的帮助下,我(ta)证明了另外两个性质,所以记录一下,趁着他还没写赶紧骗访问量,23333
性质1:一定存在最优解每一天不高兴的概率是单调不增的
这个性质最显然,证明方法就是列个式子,用$a_i$表示排序后第i个项目的不高兴概率,那么当前的期望值就是
$$P=(1-a_0)a_1+(1-a_1)a_2+(1-a_2)a_3+...+(1-a_{n-1})a_n$$
然后考虑交换两个项,$a_i$和$a_j$,现在的期望值变成了
$$P'=(1-a_0)a_1+...+(1-a_{i-1})a_j+(1-a_j)a_{i+1}+...+(1-a_{j-1})a_i+(1-a_i)a_{j+1}$$
根据$a_{i-1} \gt a_i \gt a_{i+1} \gt a_{j-1} \gt a_j \gt a_{j+1}$,
我们有
$$P-P'=(1-a_{i-1})a_i+(1-a_i)a_{i+1}+(1-a_{j-1})a_j+(1-a_j)a_{j+1}-(1-a_{i-1})a_j-(1-a_j)a_{i+1}-(1-a_{j-1})a_i-(1-a_i)a_{j+1}=(1-a_{i-1})(a_i-a_j)-a_{i+1}(a_i-a_j)-(1-a_{j-1})(a_i-a_j)+a_{j+1}(a_i-a_j)=(a_i-a_j)(-a_{i+1}-a_{i+1}+a_{j-1}+a_{j+1}) \lt 0$$
所以$P \lt P'$,即按照不高兴概率递减的顺序排列,期望更优。
性质2:一定存在最优解它选取的项目是所有项目按照不高兴的概率排序后的前缀一段加上后缀一段
这个性质也是列式子证明的。我们不妨设$A \lt B \lt C \lt D$,代表四个项目(按照不高兴概率递减的顺序排列),我们用$a,b,c,d$表示其不高兴概率,有$a\gt b\gt c\gt d$。
我们设原情况是我们从整个序列中选取了三段——[1,A],B,[D,N]。
我们设新情况是我们从整个序列中选取了三段——[1,A],C,[D,N]。
原情况的期望是$(1-a)b+(1-b)d$。
新情况的期望是$(1-a)c+(1-c)d$。
当新情况优于原情况,必然有$(1-a)b+(1-b)d>(1-a)c+(1-c)d$
解得$a+d>1$,这个就说,当$a+d>1$时,中间的点会往右靠,直到靠到后缀上;反之,中间的点会往前靠,直到靠到前缀上。所以,前缀和后缀中间不会有点被选中。
性质3:每一次选取的项目种类只有三种可能的情况:选了1个,全部选完,其他,且处于第三种状态的至多一个
前两个性质我们都是把所有项目拆成$c_i$个单独的项目考虑的,并且已经可以解决$\sum c_i \leq 10^6$时的问题了。现在我们考虑把相同项目看成一个连续的块,会有什么新的性质。
可喜可贺的是,这个性质不用列式子了,随便一想就能发现。
如果我们当前前缀的最后一个块(也就是最后一种项目)只选取了一个点,后缀的最前一个块选取了若干个点。
然后我们发现把后缀的一个名额送给前缀的最后一个块,会使期望值减少$delta$,使期望值变优。那么,我们可以说,在后缀的最后一个块露出尾巴(也就是被削减得只剩一个点)之前,我们每把一个后缀名额送给前缀,都会使得期望减少$delta$。所以我们定然会把后缀不断减少,直到其最前一个块只剩一个点为止,此时再削减最后一个块,产生的代价将不再是$delta$,所以不能继续无脑转移名额了。
可见,前缀和后缀的最后(前)一个块在某些情况只会选一个点,但绝不会同时选若干个点,都不是1而且都没有全选。
代码还是抄的jiry前辈的,毕竟我的代码功底可是非常差的。
#include <bits/stdc++.h>
using namespace std;
typedef long long lng;
typedef long double ldb;
struct data {
int cnt; ldb val;
inline data(void) {};
inline data(int a, ldb b)
: cnt(a), val(b) {};
inline void read(void) {
static int a, b;
scanf("%d/%d", &a, &b);
val = (ldb)a / b;
scanf("%d", &cnt);
}
}A[], B[];
inline bool operator < (const data &a, const data &b) {
return a.val > b.val;
}
int n, m, cas, tot;
inline ldb calc(void) {
ldb ret = 1E18, sum = ;
lng now = , rem = m;
for (int i = n; i; --i)
sum += (B[i].cnt - ) * B[i].val * ( - B[i].val) + ( - B[i].val) * B[i + ].val, rem -= B[i].cnt;
for (int i = ; i <= n; ++i ) {
rem -= B[i].cnt;
while (now <= n && rem <= )
sum -= (B[now].cnt - ) * B[now].val * ( - B[now].val) + ( - B[now].val) * B[now + ].val, rem += B[now++].cnt;
if (rem <= )break;
sum += (B[i].cnt - ) * B[i].val * ( - B[i].val) + ( - B[i - ].val) * B[i].val;
ret = min(ret, sum + (rem - ) * B[now - ].val * ( - B[now - ].val) + ( - B[now - ].val) * B[now].val + ( - B[i].val) * B[now - ].val);
}
rem = m, sum = ;
for (int i = ; i <= n; ++i) {
int mn = min(rem, (lng)B[i].cnt);
if(!mn)break; else rem -= mn, sum += (mn - ) * B[i].val * ( - B[i].val) + ( - B[i - ].val) * B[i].val;
}
return ret = min(ret, sum);
}
signed main(void) {
for (scanf("%d", &cas); cas--; ) {
scanf("%d%d", &n, &m);
for (int i = ; i <= n; ++i) {
A[i].read(); if (!A[i].cnt)--i, --n;
}
sort(A + , A + n + ); tot = ;
for (int i = ; i <= n; ++i) {
B[++tot] = data(, A[i].val);
if (--A[i].cnt) {
if (A[i].cnt > )
B[++tot] = data(A[i].cnt - , A[i].val);
B[++tot] = data(, A[i].val);
}
}
B[].val = , B[(n = tot) + ].val = ;
ldb ans = calc();
for (int i = ; i <= n; ++i)
if (i < n + - i)swap(B[i], B[n + - i]);
for (int i = ; i <= n; ++i)B[i].val = - B[i].val;
ans = min(ans, calc());
printf("%.6lf\n", (double)fabs(ans));
}
}
@Author: YouSiki
BZOJ 4030: [HEOI2015]小L的白日梦的更多相关文章
- 【BZOJ4030】[HEOI2015]小L的白日梦
[BZOJ4030][HEOI2015]小L的白日梦 题面 BZOJ 洛谷 题解 要求的是最小的不开心连续段的期望. 然后发现自己就不会做了. 然后就可以来抄题解啦. 首先来猜性质: 第一个,一定是按 ...
- HEOI2015小L的白日梦
题面链接 洛咕 sol 为什么网上面只有神仙题解啊!!! 引起我这种蒟蒻不适QAQ. 性质证明留给巨佬 然后我只贴性质了QwQ. 1.一定存在最优解每一天不高兴的概率是单调不增的. 2.一定存在最优解 ...
- P4110 [HEOI2015]小L的白日梦
传送门 题解 //minamoto #include<bits/stdc++.h> using namespace std; typedef long long ll; typedef l ...
- bzoj 4031: [HEOI2015]小Z的房间 轮廓线dp
4031: [HEOI2015]小Z的房间 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 98 Solved: 29[Submit][Status] ...
- BZOJ 4031: [HEOI2015]小Z的房间 高斯消元 MartixTree定理 辗转相除法
4031: [HEOI2015]小Z的房间 题目连接: http://www.lydsy.com/JudgeOnline/problem.php?id=4031 Description 你突然有了一个 ...
- bzoj4030【HEOI2015】小L的白日梦
题意:http://www.lydsy.com/JudgeOnline/problem.php?id=4030 sol :orz Yousiki http://www.cnblogs.com/you ...
- 【刷题】BZOJ 4031 [HEOI2015]小Z的房间
Description 你突然有了一个大房子,房子里面有一些房间.事实上,你的房子可以看做是一个包含n*m个格子的格状矩形,每个格子是一个房间或者是一个柱子.在一开始的时候,相邻的格子之间都有墙隔着. ...
- BZOJ 4031: [HEOI2015]小Z的房间 Matrix-Tree定理
题目链接: http://www.lydsy.com/JudgeOnline/problem.php?id=4031 题解: Matrix-tree定理解决生成树计数问题,其中用到高斯消元法求上三角矩 ...
- BZOJ:4031: [HEOI2015]小Z的房间
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1103 Solved: 536[Submit][Status][Discuss] Descripti ...
随机推荐
- Apex 单元测试辅助函数简介
startTest和stopTest的使用 在Apex的Test类中,有startTest和stopTest两个函数.这两个函数经常配对使用. 每个单元测试函数都只能调用它们一次. startTest ...
- LEDAPS1.3.0版本移植到windows平台----HuSr大气校正模块
这个是2012年左右放在百度空间的,谁知百度空间关闭...转移到博客园. 最近项目用到3.1.2版本的LEDAPS,新版本的使用情况会在后续文章中慢慢丰富. HuSr是将LEDAPS项目中的TM/ET ...
- Easyui datagrid combobox输入框非法输入判断与事件总结
datagrid combobox输入框非法输入判断与事件总结 by:授客 QQ:1033553122 测试环境 jquery-easyui-1.5.3 常见事件 onSelect // 选择下拉列表 ...
- DedeCMS清空删除所有文档后新建文档信息ID从1开始
方法一.登录织梦后台,找到系统->系统设置->SQL命令行工具 分别运行以下命令: 清除表中的数据,删除所有文章: truncate table `dede_arctiny`; trunc ...
- vulnhub writeup - 持续更新
目录 wakanda: 1 0. Description 1. flag1.txt 2. flag2.txt 3. flag3.txt Finished Tips Basic Pentesting: ...
- vue(1)——node.js安装使用,利用npm安装vue
node node简介 node.js也是用js开发的语言,而且是一门服务端语言,更有大神利用node写了一个操作系统出来——NodeOS node能干什么 自带下载工具: 对于我们开发前端项目,no ...
- Xml文档规则
Xml文档规则: 名字中不能包含空格 名字不能以数字或标点符号开头 左尖括号 < 后不可以有空格 起始和结束标签的大小写必须一致(严格区分大小写) XML文件中出现的第一个元素是根元素 XML文 ...
- 为Arch Linux安装搜狗输入法
我们在使用电脑的时候很多时候需要输入中文,这个时候如果没有一个中文输入法那么就是一件非常尴尬的事情了.我门现在开始在我们的archlinux来安装sougou输入法 1.我们需要配置我们的源 arch ...
- python之面相对象程序设计
一 面向对象的程序设计的由来 面向对象设计的由来见概述:http://www.cnblogs.com/linhaifeng/articles/6428835.html 面向对象的程序设计:路飞学院版 ...
- Java MultipartFile 使用记录
private void file(String path,MultipartFile file){ String separator = "/"; String originFi ...