0
点赞
收藏
分享

微信扫一扫

2021牛客暑期多校训练营5 - B (Boxes)

​​补题链接​​

可能产生最小花费​​Ex​​​的两种情况
.
一. 不使用​​​hint​​​,此时需要将所有打开所有箱子,所以​​Ex​​​就是所有花费之​​和​​​ .
二. 使用​​hint​​,刚开始使用​​hint​​,此时就知道所有的黑球的数量(​​cnt​​),当打开一个箱子后,如果这个箱子里面是​​黑球​​,则​​cnt--​​,否则​​cnt​​不变,如果当前​​cnt == 剩余的箱子数​​,则剩下的箱子里面​​全​​是​​黑球​​,如果​​cnt == 0​​,则剩下的箱子里面​​全​​为​​白球​​,​​当能根据打开的箱子确定剩下的箱子的球的颜色时​​,​​则不需要打开剩余的箱子​​,此时的花费为打开前​​m​​个箱子所要的花费,此时的概率为(剩下的箱子​​全为同色​​的概率 – 假如已经​​打开​​了​​i​​个箱子,此时的 ​​p = 0.5 ^ n - i​​,而此时的​​Exi = sum[i] * p​​),而题目中要求​​min​​的值,所以先对花费进行​​升序​​排列(因为每个箱子概率完全一样且相互独立,如果先开小的开到某个箱子可以根据推出来的黑球的数量直接判断后面箱子里球的颜色就不用继续开了),总的Ex就是2021牛客暑期多校训练营5 - B (Boxes)_补题
​sum[i] * (1 / 2) ^ (n - i)​​代表打开前​​i​​个箱子所用的花费与出现这种情况(后面的球颜色可以从当前打开的箱子的球的颜色确定)的概率的乘积(要出现此种情况,后面的球颜色必须相同),​​i​​从 ​​1 ~ n - 1​​,因为当打开第​​n - 1​​箱子时,就肯定可以确定第​​n​​个箱子的球的颜色,所以此时不用花费额外的钱。

​最后对一、二情况求个最小值即可。​

#include<iostream>
#include<algorithm>
#include<cmath>

using namespace std;

const int N = 1e5 + 10;

int n;
double ht, tol, res, w[N], sum[N];

int main(){

scanf("%d%lf", &n, &ht);

for(int i = 1; i <= n; i++){
scanf("%lf", &w[i]);
tol += w[i];
}

sort(w + 1, w + n + 1);

for(int i = 1; i <= n; i++){
sum[i] = sum[i - 1] + w[i];
}
res += ht;
for(int i = 1; i <= n - 1; i++){
res += sum[i] * pow(0.5, n - i);
}

tol = min(tol, res);

printf("%.7f", tol);

return 0;
}


举报

相关推荐

0 条评论