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 ...
随机推荐
- Linux chmod命令用法
chmod----改变一个或多个文件的存取模式(mode) Linux/Unix 的文件调用权限分为三级 : 文件拥有者.群组.其他.利用 chmod 可以藉以控制文件如何被他人所调用. 使用权限 : ...
- Dynamics AX 2012 R2 电子邮件广播错误 0x80040213
Dynamics AX 2012 R2 电子邮件广播错误 0x80040213 今天Reinhard在新环境做邮件广播测试时,发现无法发送邮件,并报以下错误: 类"CDO.Message&q ...
- 2019Java查漏补缺(一)
看到一个总结的知识: 感觉很全面的知识梳理,自己在github上总结了计算机网络笔记就很累了,猜想思维导图的方式一定花费了作者很大的精力,特共享出来.原文:java基础思维导图 自己学习的查漏补缺如下 ...
- 【案例分享】crontab执行脚本异常问题
很多时候我们会遇见这种情况,我们千辛万苦写了一个脚本,经过测试,一切正常,然后放到了crontab里面执行,结果,不管怎么配置,就是执行不正常. 结果发现环境问题,居然是这个异常的元凶. 我们先在我们 ...
- Python第二天 变量 运算符与表达式 input()与raw_input()区别 字符编码 python转义符 字符串格式化 format函数字符串格式化 帮助
Python第二天 变量 运算符与表达式 input()与raw_input()区别 字符编码 python转义符 字符串格式化 format函数字符串格式化 帮助 目录 Pychar ...
- Linux内核的冷热缓存
缓存为什么会有冷热? 究其原因,是因为对于内存的访问,可能是CPU发起的,也可以是DMA设备发起的. 如果是CPU发起的,在CPU的硬件缓存中,就会保存相应的页内容.如果这个页本来没有存在于硬件缓存中 ...
- wxPython树控件
1.树控件 树(tree)是一种通过层次结构展示信息的控件,如下图所示是树控件示例,左窗口中是树控件,在wxPython中树控件类是wx.TreeCtrl. wx.TreeCtrl中一个常用的方法有: ...
- 浏览器各个版本和系统(chrome/safari/edge/qq/360)
浏览器对象: let userAgent = navigator.userAgent.toLowerCase()console.log(userAgent) Edge: mozilla/5.0 (wi ...
- 前端——jQuery
初识jQuery 什么是jQuery? jQuery就是JavaScript和Query,是辅助JavaScript开发的库,应用广泛,形成了行业标准.它对DOM操作做了很好的封装,我们可以用jQue ...
- (hdu 6024) Building Shops
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6024 Problem Description HDU’s n classrooms are on a ...