8.13 期望题目整理
海亮回来快一个月了才开始写博客 今天整理一下最近写的题目;
最近写了一些期望 还有一些图论,dp,和一些乱七八糟的题目;
稍微整理一下思路,
对于期望 我的理解不是特别明白 因为我仅限于做过的几道题目,但是其中仍然有些回味起来不是很懂,只能说慢慢来了嗷;
不过 如果我们把握一个公式,概率和取的值乘起来然后求累和的方法求期望,是可以解决一部分题目的;
至于为什么期望总是倒退,我觉得是和我们设得状态有关的,因为有时候我们设得状态都是当前为什么,距离要满足题意还需多少天(计量单位,不限);
看几个例子;
过河;
说不上特别像期望,因为当时手推了一下样例,算出来了答案,然后模拟一边就过了,后来思考了一下,因为这个题的情况很多,所以我们可以考虑两种极端情况,他们已经是等概率的
第一种,刚到,船和人一起走,此时是L,第二种,刚到,船刚走,人需等待穿回来再走,此时是3L,所以总的期望是2L/v+走路面的距离;对于其他情况,我们都可以找到满足和为前者的情况;
#include<bits/stdc++.h> using namespace std; int n,d,p,l,v; int main() { int ca=0; while(cin>>n>>d,d) { double ans=0; for(int i=1;i<=n;i++) { cin>>p>>l>>v; d-=l; ans+=2.0*l/v; } printf("Case %d: %.3lf\n\n",++ca,ans+d); } return 0; }
介绍一下这一种经典模型,也成购物券收集问题;
问的形式大概是:有n个券,每天发一张(随意),求集齐所有券的期望天数;
还有一种就是:一个长1m的路段,雨滴是1cm,求覆盖所有地面期望雨滴数量;
这样我们转换一下,1m的路段看成100张券,雨滴看成一张券,所以模型转化;
对于这种题目,我们一般设得状态F[i]表示当前集齐i-1张还需集齐第i张得期望;
随机变量的和的期望等于这些随机变量期望之和
对于这个问题,我们需要把要求的期望分解为若干个随机变量的和。
(E(X1+X2)=E(X1)+E(X2), 当 X1, X2相互独立时)
设随机变量S表示收集到所有券所需的最少天数, 我们用Xi表示收集到(i-1)种优惠券后,还需要多少天才能收集到第i种优惠券。
X1表示收集到第一种优惠券所需天数,显然X1=1
我们来算X2,收集到第一种后,除了第一种的优惠券,其他任何一种都可以算第二种了,从而,他每天出现的概率为n-1/n,进而期望天数为n/n-1;
类似X3的期望为n/n-2;
我们有S=X1+X2+...Xn,
E(S)=E(X1)+E(X2)+...+E(Xn)。
类似的我们求下和就是答案,其实上面的式子考虑积分化简,但是我不清楚为什么直接考log是错的,算了我们还是循环吧;
其实为什么一件事情概率成功是p,那么期望是1/p的证明还是比较清楚地,证明方法很多,我自己推过了其中一种,大家可以自己理解一下;
#include<bits/stdc++.h> template<typename T>inline void read(T &x) { x=0; T f=1,ch=getchar(); while (!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar(); x*=f; } double ans,cnt; int n,x; int main() { read(n); for(int i=1;i<=n;++i) { read(x); ans=0;cnt=x; for(int j=x;j>=1;--j)ans+=cnt/j; printf("%.2lf\n",ans); } return 0; }
把握一点期望等于概率乘上所取值求累和;
所以我们这个题设状态为概率;注释都在代码里;还有一种直接求期望的,我不是很明白,我不清楚拿期望乘合不合适,有兴趣去查另一种题解8;
#include<bits/stdc++.h> using namespace std; template<typename T>inline void read(T &x) { x=0; T f=1,ch=getchar(); while (!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar(); x*=f; } const int N=2010,T=2010; double f[N][T];//f[i][j]表示在第i秒,电梯上有j个人的概率; int n,t; double p,ans; int main() { read(n);cin>>p; read(t); f[0][0]=1;//在第0时刻电梯上有0个人的概率为1; for(int i=1;i<=t;i++) { for(int j=0;j<=n;j++) if(j==0) f[i][j]=(1-p)*f[i-1][j];//考虑两种极端情况; else if(j==n) f[i][j]=f[i-1][j]+p*f[i-1][j-1];// else f[i][j]=(1-p)*f[i-1][j]+p*f[i-1][j-1]; } for(int i=1;i<=n;i++) ans+=f[t][i]*i; printf("%.12lf\n",ans); return 0; }
写完就很迷,暂时不是很明白,回来补坑,代码很好写;
//p[i]*(x+1)^3=(x^3+1+3x^2+3x)*p[i]//f[i]=(f[i-1]+3*x^2+3*x+1); //f[i-1]=x^3; //因为期望线性,所以考虑维护前缀和,应该是维护x^2,x的期望,没想清楚 //期望的和等于和的期望; //失败是对答案没有影响的,因为贡献为0,只考虑成功 //E1,E2维护一下hh #include<bits/stdc++.h> using namespace std; int n; const int N=100010; double E1[N],E2[N],p[N],f[N]; int main() { cin>>n; for(int i=1;i<=n;i++) cin>>p[i]; for(int i=1;i<=n;i++) { E1[i]=(E1[i-1]+1)*p[i]; E2[i]=(E2[i-1]+2*E1[i-1]+1)*p[i]; f[i]=f[i-1]+(3*(E1[i-1]+E2[i-1])+1)*p[i]; } printf("%.1lf\n",f[n]); return 0; }
是一道状压dp+期望;
F[i][s]表示当前进行了i-1轮,然后当前状态为S时,从第i轮到第K轮时期望最高得分,乘上概率1/n就是期望得分了;
对于转移,有取或者不取两种情况,
如果S包含的状态满足取第k种宝物的条件,则可以取或不取。不取则为f[i+1][S],取则为f[i+1][S|(1<<k-1)]+ck
所以此时f[i][S]+=max(f[i+1][S],f[i+1][S|(1<<k-1)]+ck)
2、如果S包含的状态不满足取第k种宝物的条件,则不能取,即f[i][S]+=f[i+1][S]。
所要求的答案就是f[1][0];
#include<bits/stdc++.h> using namespace std; template<typename T>inline void read(T &x) { x=0; register int f=1; register char ch=getchar(); while (!isdigit(ch)) {if(ch=='-') f=-1; ch=getchar();} while (isdigit(ch)) x=(x<<1)+(x<<3)+(ch^48), ch=getchar(); x*=f; } const int N=150; const int M=1<<16; int K,n,x,b[N],a[N]; double f[N][M]; int main() { read(K); read(n); for(int i=1;i<=n;i++) { read(a[i]); read(x); while(x) { b[i]=b[i]|(1<<(x-1));//第i种的必选x,将x位为1; read(x); } } for(int i=K;i>=1;--i) { for(int j=0;j<(1<<n);j++) { for(int k=1;k<=n;k++) { if((j&b[k])==b[k]) f[i][j]+=max(f[i+1][j],f[i+1][j|(1<<(k-1))]+a[k]); else f[i][j]+=f[i+1][j]; } f[i][j]/=n; } } printf("%.6lf\n",f[1][0]); return 0; }
刚准备提交发现自己还是不会期望,我以后再来填坑,真是让人自闭;