zoukankan      html  css  js  c++  java
  • 【2018.9.15】陈老师模拟赛1

    质量检查(quality)

    【问题描述】

    食品安全部门要检查一些食品中是否含有违禁成分。现在总共有 n 种食品待查,对于每种食品,他们需要给出是否含有这种成分。对一份样品,检测设备可以输出是否含有违禁成分。由于检测设备相当敏感,如果将多份样品混合,只要其中任何一份含有这种添加剂,设备就会输出“含有”;否则如果设备输出“不含有”,则表示混合样品中的每一种都不含有违禁成分。又由于每次检测都非常昂贵,为了减少检测次数,部门希望有策略地将一些样品混合以后进行检测。

    对于每种食品,部门都留存了两份样品,可以认为这两份样品的检测结果一定是一样的,只要确定了其中一份的结果就确定了这种食品的结果。

    根据经验,每种食品中是否含有违禁成分是独立同分布的(即相互之间没有任何关联),它们含有该成分的概率都是 k。现在你需要帮食品安全部门设计一个检测的策略,使得检测次数的期望值尽可能少。你只需要输出这个期望值。

    【输入格式】

    第一行包含一个正整数 T(1 ≤ T ≤ 105) ,表示这个测试点内的数据组数。接下来 T 行,每行两个数,分别表示 n(1 ≤ n ≤ 106) 、k(0 < k < 1) ,其中 k 最多

    包含 6 位小数。

    【输出格式】

    输出 T 行。

    每行一个浮点数,表示一组数据的答案,四舍五入精确到整数。

    【样例1输入】

    2

    6 0.1

    6 0.3

    【样例1输出】

    4

    6

     

    【子任务】

    对于 20%的数据,n ≤ 5 ;

    对于 40%的数据,n ≤ 10 ;

    对于 60%的数据,n ≤ 2×103 ;

    对于 100%的数据,n ≤ 106 ;

    在所有子任务中,均匀分布着 50%的数据,满足 T ≤ 100 。

    对于 100%的数据,保证准确答案的小数部分不大于 0.4 或不小于 0.6 。

    做这道题之前先回顾一道经典题目:你有n个相同的玻璃球,这种玻璃球从一栋m层高的楼上扔到地面时,有一个硬度区分楼层,即在这一层上面的所有层(包括这一层)把这种玻璃球扔到地面它都会碎,而在这一层下面(不包括这一层)的所有层把这种玻璃球扔到地面它都不会碎。规定扔到地面碎了的玻璃球不能再用,而没碎的玻璃球可以带到楼上继续再用,问你仅用手头的n个完好玻璃球,至少扔几次玻璃球一定能确定这个硬度区分楼层。

    如果没有玻璃球数量的限制,直接二分楼层并在对应层扔下玻璃球看碎不碎即可。但现在有玻璃球的限制,我们会发现当玻璃球的数量大于等于$lceil log( m)  ceil$时,才能保证最坏情况下(比如二分约$log_m$后才测出在1层扔就碎)有足够的玻璃球砸。

    然而当玻璃球的数量小于log的值时怎么办?可以想到dp。

    仔细思考就能注意到这样一个事情:剩下的未确定楼层一定是一个连续区间,且这个区间包含硬度区分楼层(自行证明)。只要剩下的未确定楼层的区间大小相同(即未确定的楼层数量相同)且剩余的玻璃球数量相同,那么不管剩的是哪些层,最坏情况下需要扔玻璃球的次数一定相同。比如把未确定楼层区间缩小到了6~10层或16~20层,且剩余的玻璃球数量相同,很明显它们分布硬度区分楼层的可能性是相同的,扔球检测的最坏情况也相同,而与“具体层数”无关。所以要做的扔球决策是相同的。

    总之我们只需要关心剩下的未确定楼层的区间大小,于是设$dp[i][j]$表示剩下i个楼层未确定是否是“硬度区分楼层”,且碎了j个玻璃球时所需要的最少次数。

    转移方程也很好出:$dp[i][j]=min left{ max left{dp[k][j+1], dp[i-k][j] ight} ight} | 0 leq k < i$

     - $dp[k][j-1]$就是在未确定楼层区间 从小到大第k层 扔玻璃球碎了的情况,此时范围缩小到了区间的前k层中;

     - $dp[i-k][j]$就是在未确定楼层区间 从小到大第k层 扔玻璃球没碎的情况,此时范围缩小到了区间的后i-k层中。

     - 注意:根据$dp[k][j+1]$的转移,区间从小到大第i层(即最高的一层)一定已确定为可能的 硬度区分楼层,因此$k<i$,避免上述转移再在第i层白扔碎一个玻璃球。

    这个dp的时间复杂度是$O(nm^2)$的,原因是未确定楼层的区间大小$i$最高到达$m$,再加上还要枚举最高也能到达$m$级别的$k$,效率较低。有没有优化方法?

    你一定记得dp有这样一种优化:当dp中的一维状态很大,而dp记录的值很小,我们就可以用“正难则反”的思想,把这一位状态和dp值交换。

    回来关注这道题,我们发现dp记录的值是最少扔球次数,每更新一次至多多1,而未确定楼层区间可以任意大规模地更新。因此优化一下这个dp的状态和记录的值:$dp[i][j]$表示扔i次玻璃球后,且碎了j个玻璃球时所能确定的最多楼层。

    转移方程:$dp[i][j]=dp[i-1][j]+dp[i-1][j-1]$

    为什么两者能累加?前面讲过,只要剩下的未确定楼层的区间大小相同(即未确定的楼层数量相同)且剩余的玻璃球数量相同,不管具体层数是多少,情况都一样。因此可以把在下面的楼层做的检测步骤改用到上面的楼层,能确定的楼层数就是两种决策的和。

    先打包混合检测(分块)。如:10个物品打3个包,10=3+3+4,

    3个混合物都是好的时:1+(1-k)^3 * 0

    坏的概率:1+[1-(1-k)^3]*3

    -k^2 * 1

    反比例函数,三分块的大小

    f[i]=f[i-j]+1+(g[i]*i个食品混合后有违禁成分的概率)

    倍数问题(multi)

    【题目描述】

    众所周知,小葱同学擅长计算,尤其擅长计算一个数是否是另外一个数的倍数。但小葱只擅长两个数的情况,当有很多个数之后就会比较苦恼。现在小葱给了你 n 个数,希望你从这 n 个数中找到三个数,使得这三个数的和是 K 的倍数,且这个和最大。数据保证一定有解。

    【输入格式】

    从文件 multi.in 中读入数据。第一行包括 2 个正整数 n, K。

    第二行 n 个正整数,代表给定的 n 个数。

    【输出格式】

    输出一行一个整数代表所求的和。

    【样例1输入】

    4 3

    1 2 3 4

    【样例1输出】

    9

    【样例1解释】

    选择 2、3、4。

    【子任务】

    对于 30%的数据,n ≤ 100。

    对于 60%的数据,n ≤ 1000。

    对于另外 20%的数据,K ≤ 10。

    对于 100%的数据,1 ≤ n ≤ 105,1 ≤ K ≤ 103,给定的 n 个数均不超过 108

     

    题外话:小葱是胡泽涛,出题人是钟皓曦(一对基友)

    30tps:设$mod[i][j]$表示在第1~n-1位中,两个数的和模k的值为j时的最大值,这样就预处理出了前两个数的情况。枚举第三个数x,答案就是max {$ x+mod[i-1][k-x pmod k] $} | $3 leq i leq n$

    60tps:设$mod[i][j]$表示在第1~n-1位中,一个数模k的值为j时的最大值,这样就预处理出了一个数的情况。枚举剩下两个数即可,方法类上。

    100tps:注意到模数最高只有1000,如果把所有数按照模k的余数分类,会发现每一类只有最大的3个数可能对答案有贡献。于是总共最多只有3000个数对答案有影响。设$dp[i][j]$表示选了i个数,这i个数的和模k的余数为j时 这些数的和的最大值。背包转移即可。

    忘了题目名称的题

    题外话:出题人是陈许明

    10tps:输出-1。

    20tps:暴力判是否存在没有怪物的连通块

    50tps:再输出3个样例。

    70tps:写对爆搜,枚举每个切割点四周的切割线切或不切。

    这题是典型的等级区分题。前面的暴力跟正解的最小割完全不在一个等级上……然而石神用一个不正确的算法一发A了这题数据……taijule

    先讲讲石神的算法:

    当你一开始想到爆搜的时候,你可能还会想到在添加一条切割线时,把切割线所切割的连通块给分开。有没有什么办法既能快速分开连通块,又能便捷存储块内的某些数量信息呢?这时候你会想到并查集

    但并查集只能合并,不能拆分,所以这里可以想到先把所有切割点四周的切割线都连上,然后再把多余的切割线都删去,这样就转化成了合并连通块,可以用并查集做了!

    什么样的切割线是多余的?两边已经属于一个连通块时,以及两边同时有怪物或无怪物时(即同类合并)

    把这些多余的切割线删完后,整个图就成了这种东西

    有没有注意到什么?相邻的连通块有无怪物的状态必定不相同!

    因此找一个需要在周围添加切割线最少的一个无怪物的连通块给人留着即可,其它的有无怪物的块都不加切割线,也就是全部合并,然后沉掉即可。

    这样的做法从想法上起来很优秀→_→但是有一个小细节不加考虑可能不会发现问题:

    什么样的切割线是多余的?两边已经属于一个连通块时,以及两边同时有怪物或无怪物时(即同类合并)

    两边属于同一个连通块时这条线肯定是多余的,这没得讲。但红字段所描述的同类合并你证明过么?其实它有问题:

    2019.7.22 upd:不好意思,这篇文章过得太久了,残缺的地方就鸽了

  • 相关阅读:
    Sublime : python环境
    shell:遍历目录和子目录的所有文件
    Java:方法的参数是传值还是传引用
    Sublime Text:Windows下配置C 编译环境和GDB调试环境
    代码优化的一些尝试
    go:关于变量地址的疑惑
    go:结构体的可访问性
    go:channel(未完)
    H5常见问题及解决方案。
    谷歌插件大全地址
  • 原文地址:https://www.cnblogs.com/scx2015noip-as-php/p/2018_9_15.html
Copyright © 2011-2022 走看看