zoukankan      html  css  js  c++  java
  • AGC 050 D题解

    AGC 050 D题解

    比赛的时候想到了O(N^6)的做法没敢写

    这题的数据范围非常迷惑,如果你O(N^6)的做法,请关闭这篇题解,自己尝试写出来,然后就可以AC了

    4e9的运算量只跑了 780ms,是真的神奇

    首先这题的dp样子比较显然(一眼dp题)

    可以先预处理处一个数组(p_{i,j,k,l})表示当前是第j轮,有i个人玩这个游戏,在这之前已经有k个人胜利了,最后这i个人当中又有l个胜利的概率。

    这个东西的转移比较简单,随便暴力转移也不会T。

    然后后面的步骤更加简单,每一个人分开来计算。

    (dp_{i,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("%d
    ",rest);
    	} 
    	return 0;
    }
    
    /*
    
    4 2
    1
    374341633
    748683265
    873463809
    
    */
    
  • 相关阅读:
    Spring Boot 学习随记
    Prometheus 普罗米修斯监控
    安装VC++6.0步骤及心得
    NFS 系统搭建
    Centos 搭建邮箱系统
    搭建 RTMP 服务器
    阿里云 DTS 实践
    ELK 搭建
    Prometheus 和 Grafana 安装部署
    Centos7 Nagios 搭建
  • 原文地址:https://www.cnblogs.com/gary-2005/p/14227340.html
Copyright © 2011-2022 走看看