题解:AT_abc238_h [ABC238Ex] Removing People
Solution
这种简单题为什么评分这么高。
概率期望看起来很没有意义,所以变为对全部的
发现“删人”这个事情不好记录状态,但是“加人”就很方便。我们可以设
假设我们把 R,或者 L,对这两种分别求和)。然后转化到
对于这两种状态,你需要用
复杂度
#include<bits/stdc++.h>
#define int long long
#define ffor(i,a,b) for(int i=(a);i<=(b);i++)
#define roff(i,a,b) for(int i=(a);i>=(b);i--)
using namespace std;
const int MAXN=600+10,MOD=998244353;
struct DP {int ans,cnt;}dp[MAXN][MAXN];
DP operator +(DP A,DP B) {return {(A.ans+B.ans)%MOD,(A.cnt+B.cnt)%MOD};}
DP operator *(DP A,DP B) {return {(A.ans*B.cnt+B.ans*A.cnt)%MOD,A.cnt*B.cnt%MOD};}
DP operator ^(DP A,int B) {return {A.ans*B%MOD,A.cnt*B%MOD};}
int n,op[MAXN],C[MAXN][MAXN];
int qpow(int base,int p) {
int ans=1;
while(p) {
if(p&1) ans=ans*base%MOD;
base=base*base%MOD,p>>=1;
}
return ans;
}
signed main() {
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
cin>>n;
ffor(i,0,n) {
C[i][0]=1;
ffor(j,1,i) C[i][j]=(C[i-1][j]+C[i-1][j-1])%MOD;
}
string S;
cin>>S;
ffor(i,1,n) if(S[i-1]=='R') op[i]=op[i+n]=1;
ffor(i,1,n+n) dp[i][i+1]={0,1};
ffor(len,3,n+1) for(int l=1,r=len;r<=n+n;l++,r++) {
ffor(k,l+1,r-1) {
DP tmp=(dp[l][k]*dp[k][r])^C[k-l-1+r-k-1][k-l-1];
DP ad={0,0};
if(op[l]) ad=ad+tmp,ad.ans=(ad.ans+tmp.cnt*(k-l))%MOD;
if(!op[r]) ad=ad+tmp,ad.ans=(ad.ans+tmp.cnt*(r-k))%MOD;
dp[l][r]=dp[l][r]+ad;
}
}
int ans=0;
ffor(i,1,n) ans=(ans+dp[i][i+n].ans)%MOD;
ffor(i,1,n) ans=ans*qpow(i,MOD-2)%MOD;
cout<<(ans%MOD+MOD)%MOD;
return 0;
}