gym 102059 C.Dstorv题解
首先可以发现最终一定是一个分界点 i , ( i < n ) i,(i<n) i,(i<n)满足下标≤i的中留下 A A A个全部向左,其余的留下 B B B个全部向右。特殊的 i i i是那 A A A中的一个, i + 1 i+1 i+1是那 B B B中的一个。
我们可以想到 d p dp dp状态, f i , j f_{i,j} fi,j表示考虑第 i i i位,右边有 j j j个向左过来。
转移:
(
a
i
=
′
H
′
)
(a_i='H')
(ai=′H′),
f
i
−
1
,
j
+
1
→
f
i
,
j
f_{i-1,j+1}\rightarrow f_{i,j}
fi−1,j+1→fi,j
( a i = ′ R ′ ) (a_i='R') (ai=′R′):
- f i , j − 1 ∗ h h + r → f i , j f_{i,j-1}*\large{\frac{h}{h+r}}\rightarrow f_{i,j} fi,j−1∗h+rh→fi,j,(向左的一个消失)
- f i − 1 , j ∗ r h + r → f i , j f_{i-1,j}*\large{\frac{r}{h+r}}\rightarrow f_{i,j} fi−1,j∗h+rr→fi,j
初始化: f 0 , A = 0 f_{0,A}=0 f0,A=0.
对于向右的一样处理。
时间复杂度 O ( n 2 ) O(n^2) O(n2)。
Code:
/*
{By GWj
*/
#pragma GCC optimize(2)
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define FREO freopen("check.out","w",stdout)
#define rep(a,b) for(int a=0;a<b;++a)
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define R(a) cin>>a
#define R2(a,b) cin>>a>>b
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
const int MOD=1e9+7;
LL quick(LL A,LL B){
if(B==0) return 1;
LL tmp=quick(A,B>>1);
tmp*=tmp;
tmp%=MOD;
if(B&1)
tmp*=A,tmp%=MOD;
return tmp;
}
LL inv(LL A) {return quick(A,MOD-2);}
LL l,r,h,R;
int n,A,B;
vector<vector<LL> > dp1,dp2;
vector<vector<LL> > work(string s){
s='$'+s;
vector<vector<LL > > dp=vector<vector<LL> > (5000+2,vector<LL>(5000+2,0.0));
dp[0][A]=1.0;
rb(i,1,n){
rb(j,0,n){
if(s[i]=='L'){
dp[i][j]=dp[i-1][j+1];
}
else{
if(!j) continue;
dp[i][j]=dp[i-1][j]*r%MOD+dp[i][j-1]*l%MOD;
if(dp[i][j]>=MOD) dp[i][j]-=MOD;
}
}
}
return dp;
}
int main(){
fastio;
cin>>n>>R>>h;
l=(h)*inv(R+h)%MOD;
r=(R)*inv(R+h)%MOD;
string s;
R(s);
rep(i,n)
if(s[i]=='H') s[i]='L';
R2(B,A);
dp1=work(s);
swap(A,B);
swap(l,r);
reverse(ALL(s));
rep(i,n)
if(s[i]=='L') s[i]='R';
else s[i]='L';
dp2=work(s);
LL rest=0;
rb(i,0,n){
int ii=n-i;
rest+=dp1[i][0]*dp2[ii][0]%MOD;
if(rest>=MOD) rest-=MOD;
}
cout<<rest<<endl;
return 0;
}