正好遇到,然后第一次自己推出来了o(* ̄▽ ̄*)ブ
题目大意:有n面镜子,每天会询问一面镜子一个问题,从第一面的镜子开始询问你漂不漂亮,每面镜子在询问的时候,会有pi /100的概率告诉你漂亮,然后如果这是第n面镜子,你就会停止询问并变得开心,否则你会在下一天询问下一面镜子; 反之有1-(pi /100)的概率告诉你,你不漂亮,那你就会伤心,然后在下一天询问第一面镜子。
求变的开心需要询问次数的期望。n<=2e5
E(x)表示当前询问第x面镜子,变得开心还需询问的天数的期望值。
有:
E(n)=(1-(pn/100))*E(1)+1;
E(i)=(pi/100)*E(i+1)+(1-(pi/100))*E(1)+1;
然后就 可以根据第二个式子 把E(i)全都用E(1)表示,然后 用第一个式子 解出E(1),也就是答案
2019-12-06
```````````````````````
然后!div1的c和div2的e难了(:3_``)
不同地方在于div2e固定(1-pi)返回第1点,div2是q个操作,使u成为或不成为特异点,对每个i回到存在的最近的特异点。
然后之前看的题解说:
“
有个非常经典的dp是fi表示期望多少次从i走到i+1, 但是按此方法并不能(至少我不会)导出一个方便维护修改的做法。
这时可以转换思路,考虑另一种DP,设fi表示i这个点期望经过多少次,则有fi=f(i+1)/pi,f(n+1)=1
”
所以 就有了新做法,但是我还是不怎么会打这份代码出来,不过 能理解。
#include<bits/stdc++.h> #define debug printf("#"); #define pb push_back using namespace std; typedef long long ll; const int mod=998244353; const int maxn=1e6+50; /* f[i]表示i点期望经过多少次f[i]=f[i+1]/pi f[n+1]=1; */ set<int>se; set<int>::iterator it; inline ll kpow(ll a,ll b) { ll ans=1;a%=mod; while(b) { if(b&1)ans=ans*a%mod; a=a*a%mod; b>>=1; } return ans; } ll p[maxn],f[maxn],s[maxn]; int main() { int n,q; ll inv100=kpow(100,mod-2); scanf("%d%d",&n,&q); for(int i=1;i<=n;i++) { scanf("%lld",&p[i]); p[i]=p[i]*inv100%mod; } f[n+1]=1;s[n+1]=0; for(int i=n;i>=1;i--) { f[i]=f[i+1]*p[i]%mod; s[i]=(s[i+1]+kpow(f[i],mod-2))%mod; } ll ans=s[1];int u,pre,last; se.insert(1);se.insert(n+1); while(q--) { scanf("%d",&u); it=se.lower_bound(u);it--; pre=*it; it=se.upper_bound(u); last=*it; if(se.count(u)) { ans+=((s[pre]-s[u]+mod)%mod)*((f[last]-f[u]+mod)%mod)%mod; ans%=mod; se.erase(u); } else { ans-=((s[pre]-s[u]+mod)%mod)*((f[last]-f[u]+mod)%mod)%mod; ans=(ans+mod)%mod; se.insert(u); } printf("%lld ",ans); } }
2019-12-07
做不会概率题,但规律还是要一点一点总结的。
做了两道题,做法都有点像。
题目大意:一个长度为n+1的棋盘,从0到n。现在有一颗棋子在位置m,想要把棋子移到位置0。每一次移动,除了n点以外,每个位置有概率p向0点方向移动1格,概率(1-p)向n点方向移动1格,在n点位置就 只能向0点方向移动,询问从m点移动到0点的期望移动次数。
n<=1e6, 答案对1e9+7取模。 概率p以最简分数给出。
题解的做法是推出公式。然后其中有一个比较重要的也常用的:
设E(x)为在位置x移动到0的期望次数,则:E(x)=pE(x-1)+(1-p)E(x+1)+1;
因为:在E(x)有概率p变成E(x-1),有概率(1-p)变成E(x+1),所以E(x)的值是 p概率下E(x-1)的值 加上 (1-p)概率下E(x+1)的值,还要加上本身移动的次数是1。
在知道这个公式后,距离答案就是一些神奇的转换了。 但是我连这个公式都不会。
然后
题目大意:有n种邮票,每次买1张,买到的邮票的种类是等概率1/n,购买第k次需要的付出的价值是k,问买到n种邮票时期望付出的价值。n<=10000,保留小数点后2位输出答案。
题解是递推,有类似的公式:
设Ef(x)为当前买了x种邮票,还需要购买邮票的期望张数。则:Ef(x)=x/n*Ef(x)+(n-x)/n*Ef(x+1)+1;
因为:在Ef(x)有概率x/n买到之前买过的邮票(n张中有x张买过了),即是,有概率x/n变成Ef(x);有概率(n-x)/n买到之前没买过的邮票,即是,有概率(n-x)/n变成Ef(x+1);然后是本身购买次数是1。
所以 化简一下 有:Ef(x)=Ef(x+1)+n/(n-x);
设Eg(x)为当前买了x种邮票,还需要购买邮票的期望价格。则:Eg(x)=x/n*( Eg(x)+Ef(x)+1 )+(n-x)/n*( Eg(x+1)+Ef(x+1)+1 )
这个我有点难理解。
大概是: 在Eg(x)有x/n的概率买到买过的邮票,所以之后购买的价格都因为这次操作加1 所以 原状态的费用叠加Ef(x) 再加上本身(当前,不计前面..?)费用1, 就是x/n*( Eg(x)+Ef(x)+1 );
在Eg(x)有(n-x)/n的概率买到没买过的邮票,所以同理 是(n-x)/n*(Eg(x+1)+Ef(x+1)+1)。
化简有:Eg(x)=x/(n-x)*Ef(x)+Eg(x+1)+Ef(x+1)+n/(n-x)。
然后就是for循环递推到Eg(0)即为答案。
2019-12-04