前言
考试时有道题目用到了【折半搜索】
老师推荐了这道经典题目让大家练习【前后部分算法不同】的题目
虽然不知道我有没有时间做,好歹先把题目记录一下,免得以后找不到了qwq
题目
Input
Output
(答案保留4位小数)
Sample Input
1 3 3 4 50 3 50 7 50 5 1 7 1 3 2
Sample Output
0.7500
【数据范围】
分析
JZOJ现成的题解,悄悄贴一贴:
暴力(20 分)
暴力枚举状态,然后设状态 F[i][j][k]表示做完前 i 个数,用了 j 的钱,k 的钻石买的最大物品,转移个背包类似。 复杂度:
正解(100 分)
先设 F[i][j]表示我们最终由 i 个钻石,要买 j 个物品,至少要多少金钱。 这是非常简单的 01 背包问题。但是如果把全部的状态枚举出来会超时,那 么我们考虑用 Meet in the middle 来解决。
将盒子分为前后两个部分 a,b。对于前 a 部分,我们暴力枚举状态 S(V, D, P),表示获得 V 的金钱,D 个钻石,概率为 P。将状态按 D 的值分类。因 为一个盒子只能拿一个钻石,所以 D<=a。接着对于钻石数相同的状态,我 们将他们按金钱大小从小到大排序,并维护出概率的前缀和。这里的复杂度 时 。
对于后半部分,我们同样也用暴力来枚举出所有的状态,设当前状态为 S(V, D, P),再枚举 a 部分中获得了 t 个钻石,最终我们买了 i 件物品。设 a 部分获得的金钱是 G,则必然满足下面的关系式: F[t+D][i] <= V+G < F[t+D][i+1] 因为首先要够钱,其次钱不能太多。那么 G 的范围可以二分得出。然后 对概率求区间和,然后贡献到答案中。这里的复杂度是 。计 算一下可得,当时复杂度最优。 复杂度:
图片版