Ybt#452-序列合并【期望dp】
正題
題目鏈接:https://www.ybtoj.com.cn/contest/113/problem/2
題目大意
一個空序列,每次往末尾加入一個[1,m][1,m][1,m]中的隨機一個數。如果末尾兩個數相同都為xxx且(x<t)(x<t)(x<t),那么將它們合并成x+1x+1x+1。
如果序列長度為nnn且無法合并則結束,求序列期望和。
n,m∈[1,103],t∈[1,109]n,m\in[1,10^3],t\in[1,10^9]n,m∈[1,103],t∈[1,109]
解題思路
首先顯然地t=min{n+m?1,t}t=min\{n+m-1,t\}t=min{n+m?1,t}。
之后考慮序列中的每一個位置可能的數,因為每種情況都有可能,所以我們需要算概率先,設pi,jp_{i,j}pi,j?表示剩余iii個位置時出現jjj的概率,那么有pi,j=1m×[j≤m]+pi,j?12p_{i,j}=\frac1m\times [j\leq m]+p_{i,j-1}^2pi,j?=m1?×[j≤m]+pi,j?12?(直接出現或者合并出來)。
設pi,j×qi,jp_{i,j}\times q_{i,j}pi,j?×qi,j?表示剩下iii個位置且第一個最終是jjj的概率,那么有qi,j=1?pi?1,j×[j<t]q_{i,j}=1-p_{i-1,j}\times [j<t]qi,j?=1?pi?1,j?×[j<t](qi,jq_{i,j}qi,j?就表示在出現了jjj的前提下不變的概率,減去會變的概率就好了)。
但是因為每個位置的概率不是獨立的,所以不能直接用這個來算答案。
設pi,j×gi,jp_{i,j}\times g_{i,j}pi,j?×gi,j?表示在剩下iii個位置且第一個最終是jjj時和的期望和(注意期望=概率*次數),pi,j×fi,jp_{i,j}\times f_{i,j}pi,j?×fi,j?表示剩下iii個位置時第一個出現過jjj的情況的期望和,ansians_iansi?表示剩下iii個位置時的期望和。
那么有
ansi=∑j=1tpi,j×gi,jans_i=\sum_{j=1}^{t}p_{i,j}\times g_{i,j}ansi?=j=1∑t?pi,j?×gi,j?
考慮ggg的遞推式有
gi,j=qi,j×j+ansi?1?pi?1,j×fi?1,jg_{i,j}=q_{i,j}\times j+ans_{i-1}-p_{i-1,j}\times f_{i-1,j}gi,j?=qi,j?×j+ansi?1??pi?1,j?×fi?1,j?
(有qi,jq_{i,j}qi,j?的概率最終是jjj,填完剩下的,且下一個不能出現jjj)
考慮fff的遞推式有
fi,j=gi,j+(1?qi,j)fi,j+1f_{i,j}=g_{i,j}+(1-q_{i,j})f_{i,j+1}fi,j?=gi,j?+(1?qi,j?)fi,j+1?
(第一種是最終不變,第二種是變成了j+1j+1j+1的情況)
這樣就可以遞推了,時間復雜度O(n2)O(n^2)O(n2)
code
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; const ll N=2100,P=1e9+7; ll n,m,t,p[N][N],q[N][N],g[N][N],f[N][N],ans[N]; ll power(ll x,ll b){ll ans=1;while(b){if(b&1)ans=ans*x%P;x=x*x%P;b>>=1;}return ans; } signed main() {freopen("sequence.in","r",stdin);freopen("sequence.out","w",stdout);scanf("%lld%lld%lld",&n,&m,&t);ll inv=power(m,P-2);t=min(t,n+m-1);for(ll i=1;i<=n;i++)for(ll j=1;j<=t;j++){p[i][j]=(inv*(j<=m)+p[i-1][j-1]*p[i][j-1]%P)%P;q[i][j]=(1-(j<t)*p[i-1][j]+P)%P;}for(ll i=1;i<=n;i++){for(ll j=t;j>=1;j--){if(j!=t)g[i][j]=(q[i][j]*j%P+ans[i-1]-f[i-1][j]*p[i-1][j]%P+P)%P;elseg[i][j]=(q[i][j]*j%P+ans[i-1])%P;f[i][j]=(g[i][j]%P+(1-q[i][j])*f[i][j+1]%P)%P;(ans[i]+=g[i][j]*p[i][j])%=P;}}printf("%lld\n",ans[n]);return 0; }總結
以上是生活随笔為你收集整理的Ybt#452-序列合并【期望dp】的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 怎么才能让电脑运行流畅不卡顿电脑如何才能
- 下一篇: AT3950-[AGC022E]Medi