首先特殊牌型直接特判。
而後剩下的部分能夠直接\(dp\),直接把全部能夠存的所有帶進去大力\(dp\)就好了。
發現每多一張牌胡的本質就是把一個刻字換成槓子,因此這兩個東西記錄在一塊兒就好了。
那麼狀態就是\(f[i][0/1/2/3/4][0/1/2][0/1/2][0/1]\)
分別表示刻字、槓子、順子的數量,\(i-1,i,i+1\)的順子數量,\(i,i+1,i+2\)的順子的數量,以及是否已經有對子。
轉移比較容易。ios
#include<iostream> #include<cstdio> #include<cstdlib> #include<cstring> #include<cmath> #include<algorithm> #include<vector> using namespace std; #define ll long long #define MAX 140 int Read() { char ch[3];scanf("%s",ch); if(ch[0]=='E')return 28;if(ch[0]=='S')return 29; if(ch[0]=='W')return 30;if(ch[0]=='N')return 31; if(ch[0]=='Z')return 32;if(ch[0]=='B')return 33; if(ch[0]=='F')return 34;if(ch[0]=='0')return 0; int x=ch[0]-48;if(ch[1]=='p')x+=9;if(ch[1]=='s')x+=18; return x; } ll C[MAX][MAX]; int n,s[MAX];bool book[MAX]; ll f[35][6][3][3][2]; int pre[14]={0,1,9,10,18,19,27,28,29,30,31,32,33,34}; int bin[10]={1,2,4,8,16,32,64,128,256,512}; void cmax(ll &x,ll y){x=max(x,y);} int main() { for(int i=0;i<10;++i)C[i][0]=1; for(int i=1;i<10;++i) for(int j=1;j<=i;++j)C[i][j]=C[i-1][j]+C[i-1][j-1]; int T,x;scanf("%d",&T); while(T--) { for(int i=1;i<=34;++i)s[i]=4,book[i]=false; while((x=Read()))s[x]-=1; while((x=Read()))book[x]=true; ll ans=0; //Task1 { bool fl=true;int mx=0;ll ret=1; for(int i=1;i<=13;++i) if(!s[pre[i]]){fl=false;break;} else mx=max(mx,(s[pre[i]]-1)*(book[pre[i]]?2:1)),ret=ret*(book[pre[i]]?2:1)*s[pre[i]]; if(fl)ret=ret*mx*13/2,ans=max(ans,ret); } //Task2 { vector<int> val; for(int i=1;i<=34;++i) if(s[i]>=2)val.push_back((book[i]?4:1)*(s[i]*(s[i]-1)/2)); sort(val.begin(),val.end()); if(val.size()>=7) { ll ret=1; for(int i=7;i;--i)ret*=val.back(),val.pop_back(); ans=max(ans,ret*7); } } //Task3 { memset(f,0,sizeof(f)); f[0][0][0][0][0]=1; for(int i=1;i<=34;++i) for(int j=0;j<5;++j) for(int k=0;k<3&&j+k<=4&&k<=s[i];++k) { if(k>0&&(i==10||i==19||i>=28||i==11||i==20))break; for(int l=0;l<3&&j+k+l<=4&&k+l<=s[i];++l) { if(l>0&&(l==9||i==18||i==27||i==10||i==19||i>=28))break; if(!f[i-1][j][k][l][0]&&!f[i-1][j][k][l][1])continue; for(int m=0;k+l+m<=s[i]&&m<3;++m) { if(m>0&&(i==9||i==18||i>=27))continue; if(s[i]>=4+k+l+m) { cmax(f[i][j+1+k][l][m][0],(book[i]?16:1)*f[i-1][j][k][l][0]); cmax(f[i][j+1+k][l][m][1],(book[i]?16:1)*f[i-1][j][k][l][1]); } if(s[i]>=3+k+l+m) { cmax(f[i][j+1+k][l][m][0],(book[i]?bin[3+k+l+m]:1)*C[s[i]][3+k+l+m]*f[i-1][j][k][l][0]); cmax(f[i][j+1+k][l][m][1],(book[i]?bin[3+k+l+m]:1)*C[s[i]][3+k+l+m]*f[i-1][j][k][l][1]); } if(s[i]>=2+k+l+m) { cmax(f[i][j+k][l][m][1],(book[i]?bin[2+k+l+m]:1)*C[s[i]][2+k+l+m]*f[i-1][j][k][l][0]); } if(s[i]>=k+l+m) { cmax(f[i][j+k][l][m][0],(book[i]?bin[k+l+m]:1)*C[s[i]][k+l+m]*f[i-1][j][k][l][0]); cmax(f[i][j+k][l][m][1],(book[i]?bin[k+l+m]:1)*C[s[i]][k+l+m]*f[i-1][j][k][l][1]); } } } } ans=max(ans,f[34][4][0][0][1]); } printf("%lld\n",ans); } }