Boxes
Posted Jozky86
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Boxes相关的知识,希望对你有一定的参考价值。
题意:
有n个盒子,每个盒子里要么是黑球,要么是白球,你可以花C的代码得知剩下所有盒子中黑球数量和白球数量,(只是知道总数量,并不知道具体哪个盒子里是什么),你可以可以花费wi的代价开第i个箱子。问想知道所有盒子里球的情况,花费的最少期望是多少?
题解:
首先这个C最多只用花一次,且第一次花,因为你第一次花完之后,就知道黑白所有的数量,如果你开了箱子,剩下的箱子反推就知道,所以这个C只用花一次。
如果只花一次C,那我们就要考虑剩下的箱子打开情况,按照wi升序排列,我们肯定优先打开花费小的箱子,一直开,直到开到一个后缀全是同色的位置。这样的代价:
C
+
∑
w
i
(
1
−
1
/
(
2
n
−
i
)
)
C+\\sum wi(1-1/(2^{n-i}))
C+∑wi(1−1/(2n−i))
公式得到过程:
如果我们当前打算开第i个,那么就还有n-i个没开,如果不继续开箱子,说明后面都是同色的,后面同色的概率是
1
/
2
n
−
i
1/2^{n-i}
1/2n−i,如果第i个箱子开,就说明后面不都是同色的,概率就是
1
−
1
/
2
n
−
i
1-1/2^{n-i}
1−1/2n−i,期望就再乘上wi
当然,可以不整那么多虚的,有可能直接打开所有盒子的总花费更优,此时打开所有盒子的概率都是1,总期望就是
∑
i
=
1
n
w
i
\\sum_{i=1}^nwi
∑i=1nwi
两个情况取最小
代码:
#include<bits/stdc++.h>
#define debug(a,b) printf("%s = %d\\n",a,b);
using namespace std;
typedef long long ll;
typedef pair<int, int> PII;
//Fe~Jozky
const ll INF_ll=1e18;
const int INF_int=0x3f3f3f3f;
inline ll read(){
ll s=0,w=1ll;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1ll;ch=getchar();}
while(ch>='0'&&ch<='9') s=s*10ll+((ch-'0')*1ll),ch=getchar();//s=(s<<3)+(s<<1)+(ch^48);
return s*w;
}
void rd_txt(){
#ifdef ONLINE_JUDGE
#else
freopen("in.txt","r",stdin);
#endif
}
const int maxn=1e5+9;
long double a[maxn];
long double sum[maxn];
long double poww(long double a,ll b){
long double ans=1;
while(b){
if(b&1)ans*=a;
a*=a;
b>>=1;
}
return ans;
}
int main()
{
//rd_txt();
int n;double c;
cin>>n>>c;
for(int i=1;i<=n;i++)cin>>a[i];
sort(a+1,a+1+n);
for(int i=1;i<=n;i++)sum[i]=sum[i-1]+a[i];
long double ans=c;
long double t=1.0;
for(int i=1;i<=n;i++){
ans+=a[i]*(1.0-1.0/poww(2,n-i));
}
ans=min(ans,sum[n]);
printf("%.8Lf\\n",ans);
return 0;
}
以上是关于Boxes的主要内容,如果未能解决你的问题,请参考以下文章