概述
AGC 050 D题解
比赛的时候想到了O(N^6)的做法没敢写
这题的数据范围非常迷惑,如果你O(N^6)的做法,请关闭这篇题解,自己尝试写出来,然后就可以AC了
4e9的运算量只跑了 780ms,是真的神奇
首先这题的dp样子比较显然(一眼dp题)
可以先预处理处一个数组 p i , j , k , l p_{i,j,k,l} pi,j,k,l表示当前是第j轮,有i个人玩这个游戏,在这之前已经有k个人胜利了,最后这i个人当中又有l个胜利的概率。
这个东西的转移比较简单,随便暴力转移也不会T。
然后后面的步骤更加简单,每一个人分开来计算。
设 d p i , l , r dp_{i,l,r} dpi,l,r表示当前到达这个钦定的人,前面还剩下l个,后面还剩下r个人,到达这部的概率的概率。
转移直接枚举上一维的 l ′ , r ′ l',r' l′,r′就行了。
所以这题的区分度主要在于你是否敢写
/*
{
######################
# Author #
# Gary #
# 2020 #
######################
*/
#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 check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
//inline int read(){
// int x=0;
// char ch=getchar();
// while(ch<'0'||ch>'9'){
// ch=getchar();
// }
// while(ch>='0'&&ch<='9'){
// x=(x<<1)+(x<<3)+(ch^48);
// ch=getchar();
// }
// return x;
//}
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
/*}
*/
const int MOD=998244353;
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;
}
int invm;
int n,m;
int p[43][43][43][43];
int dp[43][43][43];
int good[43][43][43];
/*
dp[i][j][l][m]=p[i-1][j][l]*p[n-i][j-1][m]
*/
int main(){
scanf("%d%d",&n,&m);
invm=quick(m,MOD-2);
rb(i,0,n) p[i][0][0][0]=1;
rb(i,1,m+1) rb(j,i-1,m+1) p[0][i][j][0]=1;
rb(i,1,n){
rb(j,1,m+1){//now
rb(k,j-1,m+1){
rb(l,0,i){
if(l&&(m-(j-1))>=(m-k-(l-1))){
p[i][j][k][l]+=1ll*p[i-1][j][k][l-1]*(m-k-(l-1))%MOD*quick(m-(j-1),MOD-2)%MOD;
}
if(m-(j-1)>=(k+l-(j-1))){
p[i][j][k][l]+=1ll*p[i-1][j][k][l]*(k+l-(j-1))%MOD*quick(m-(j-1),MOD-2)%MOD;
}
p[i][j][k][l]%=MOD;
}
}
}
}
rb(now,1,n){
memset(good,0,sizeof(good));
memset(dp,0,sizeof(dp));
int rest=0;
dp[0][now-1][n-now]=1;
rb(i,1,m){
rb(l,0,now-1){
rb(r,0,n-now){
rb(j,0,(now-1)-l){
rb(k,0,(n-now)-r){
dp[i][l][r]+=1ll*dp[i-1][l+j][r+k]*(1-good[i-1][l+j][r+k]+MOD)%MOD*p[r+k][i-1][(n-1-(l+j)-(r+k))][k]%MOD*p[l+j][i][n-1-(l+j)-r][j]%MOD;
dp[i][l][r]%=MOD;
}
}
int res=m-(n-1-l-r);
good[i][l][r]=res*quick(m-(i-1),MOD-2)%MOD;
rest+=1ll*dp[i][l][r]*good[i][l][r]%MOD;
rest%=MOD;
}
}
}
printf("%dn",rest);
}
return 0;
}
/*
4 2
1
374341633
748683265
873463809
*/
最后
以上就是动人冰棍为你收集整理的AGC 050 D题解AGC 050 D题解的全部内容,希望文章能够帮你解决AGC 050 D题解AGC 050 D题解所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复