Boxes

Posted Jozky86

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Boxes相关的知识,希望对你有一定的参考价值。

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(11/(2ni))
公式得到过程:
如果我们当前打算开第i个,那么就还有n-i个没开,如果不继续开箱子,说明后面都是同色的,后面同色的概率是 1 / 2 n − i 1/2^{n-i} 1/2ni,如果第i个箱子开,就说明后面不都是同色的,概率就是 1 − 1 / 2 n − i 1-1/2^{n-i} 11/2ni,期望就再乘上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的主要内容,如果未能解决你的问题,请参考以下文章

D. Boxes Packing

POJ 1475 Pushing Boxes

第十周 Leetcode 546. Remove Boxes (HARD) 记忆化搜索

动态规划——Remove Boxes

uva103-Stacking_Boxes

双向链表 Boxes in a Line UVA - 12657