zoukankan      html  css  js  c++  java
  • 【LOJ #3084】【GXOI / GZOI2019】—宝牌一大堆(DP)

    传送门


    首先把国士无双和七对子判掉

    实际上可以发现杠根本没用
    因为(43)>(44)2{4choose 3}>{4choose 4}*2

    f[i][j][k][l][0/1]f[i][j][k][l][0/1]
    表示前ii种,已经凑出jj个面子,有k,lk,l个从i1,i2i-1,i-2开始凑的顺子,是否有雀头
    枚举当前选择新凑几个顺子,凑刻子,雀头
    随便乱dpdp一下就完了

    #include<bits/stdc++.h>
    using namespace std;
    const int RLEN=1<<20|1;
    inline char gc(){
        static char ibuf[RLEN],*ib,*ob;
        (ob==ib)&&(ob=(ib=ibuf)+fread(ibuf,1,RLEN,stdin));
        return (ob==ib)?EOF:*ib++;
    }
    #define gc getchar
    inline int read(){
        char ch=gc();
        int res=0,f=1;
        while(!isdigit(ch))f^=ch=='-',ch=gc();
        while(isdigit(ch))res=(res+(res<<2)<<1)+(ch^48),ch=gc();
        return f?res:-res;
    }
    #define ll long long
    #define re register
    #define pii pair<int,int>
    #define fi first
    #define se second
    #define pb push_back
    #define cs const
    #define bg begin
    #define poly vector<int>  
    inline void chemx(ll &a,ll b){a<b?a=b:0;}
    inline void chemn(int &a,int b){a>b?a=b:0;}
    cs int N=40;
    int a[N],b[N],n;
    char s[5];
    int tot;
    ll q[N],f[N][5][3][3][2],c[5][5],ans;
    inline void calc_qdz(){
    	for(int i=1;i<=tot;i++)q[i]=0;
    	tot=0;ll res=7;
    	for(int i=1;i<=34;i++)
    		if(a[i]>=2)q[++tot]=c[a[i]][2]*max(1,b[i]<<2);
    	if(tot<7)res=0;
    	sort(q+1,q+tot+1,greater<int>());
    	for(int i=1;i<=7;i++)res*=q[i];
    	chemx(ans,res);
    }
    int gp[14]={0,1,9,10,18,19,27,28,29,30,31,32,33,34};
    inline void calc_gsws(){
    	ll res=0;
    	for(int i=1;i<=13;i++){
    		if(a[gp[i]]<2)continue;
    		ll tmp=1;
    		for(int j=1;j<=13;j++){
    			if(i==j)tmp*=c[a[gp[i]]][2]*max(1,b[gp[j]]<<2);
    			else tmp*=c[a[gp[j]]][1]*max(1,b[gp[j]]<<1);
    		}
    		chemx(res,tmp);
    	}
    	chemx(ans,res*13);
    }
    inline void calc_342(){
    	memset(f,0,sizeof(f));
    	f[1][0][0][0][0]=1;
    	for(int i=1;i<=34;i++){
    		for(int j=0;j<=4;j++){
    			for(int k=0;k<=2&&j+k<=4;k++){
    				if(k&&(i==10||i==19||i>=28))break;
    				for(int l=0;l<=2&&j+k+l<=4;l++){
    					if(l&&(i==10||i==19||i>=28))break;
    					for(int p=0;p<=a[i]-k-l&&j+p<=4;p++){
    						int u=k+l+p;
    						for(int o=0;o<=1;o++)
    						chemx(f[i+1][j+l][p][k][o],f[i][j][k][l][o]*c[a[i]][u]*max(1,b[i]<<u));
    						if(k+p+l<=a[i]-3&&j+l+1<=4){
    							u=k+l+p+3;
    							for(int o=0;o<=1;o++)
    							chemx(f[i+1][j+l+1][p][k][o],f[i][j][k][l][o]*c[a[i]][u]*max(1,b[i]<<u));
    						}
    						if(k+p+l<=a[i]-2){
    							u=l+k+p+2;
    							chemx(f[i+1][j+l][p][k][1],f[i][j][k][l][0]*c[a[i]][u]*max(1,b[i]<<u));
    						}
    					}
    				}
    			}
    		}
    	}
    	chemx(ans,f[35][4][0][0][1]);
    }
    inline void solve(){
    	for(int i=1;i<=34;i++)a[i]=4,b[i]=0;ans=0;
    	while(1){
    		scanf("%s",s+1);
    		if(strlen(s+1)==1){
    			if(s[1]=='0')break;
    			switch (s[1]){
    				case 'E':a[28]--;break;
    				case 'S':a[29]--;break;
    				case 'W':a[30]--;break;
    				case 'N':a[31]--;break;
    				case 'Z':a[32]--;break;
    				case 'B':a[33]--;break;
    				case 'F':a[34]--;break;
    			}
    		}
    		else{
    			switch (s[2]){
    				case 'm':a[s[1]-'0']--;break;
    				case 'p':a[s[1]-'0'+9]--;break;
    				case 's':a[s[1]-'0'+18]--;break;
    			}
    		}
    	}
    	while(1){
    		scanf("%s",s+1);
    		if(strlen(s+1)==1){
    			if(s[1]=='0')break;
    			switch (s[1]){
    				case 'E':b[28]++;break;
    				case 'S':b[29]++;break;
    				case 'W':b[30]++;break;
    				case 'N':b[31]++;break;
    				case 'Z':b[32]++;break;
    				case 'B':b[33]++;break;
    				case 'F':b[34]++;break;
    			}
    		}
    		else{
    			switch (s[2]){
    				case 'm':b[s[1]-'0']++;break;
    				case 'p':b[s[1]-'0'+9]++;break;
    				case 's':b[s[1]-'0'+18]++;break;
    			}
    		}
    	}
    	calc_qdz();
    	calc_gsws();
    	calc_342();
    	cout<<ans<<'
    ';
    }
    inline void init(){
    	for(int i=0;i<=4;i++){
    		c[i][0]=c[i][i]=1;
    		for(int j=1;j<i;j++)
    		c[i][j]=c[i-1][j-1]+c[i-1][j];
    	}
    }
    int main(){
    	int T=read();init();
    	while(T--)solve();
    }
    
  • 相关阅读:
    向代码致敬,寻找你的第83行
    佛系程序员的月薪五万指南
    再谈全局网HBase八大应用场景
    如何避免HBase写入过快引起的各种问题
    阿里云MaxCompute被Forrester评为全球云端数据仓库领导者
    为了让开发者写MaxCompute SQL更爽,DataWorks 增强SQL 编辑器功能
    《CDN 之我见》原理篇——CDN的由来与调度
    Installing GCC (C++ Compiler and Development Tools)
    Gems installation
    Fedora23
  • 原文地址:https://www.cnblogs.com/stargazer-cyk/p/12328486.html
Copyright © 2011-2022 走看看