I.Chiitoitsu
- 一个概率dp
- 题目是让求摸到麻将中七个对子胡牌的期望局数(11,22,33诸如此类)
- 这个麻将有34种不同类型的牌,每一种类型的牌具有4张,初始时手中有13张牌,相同的牌至多有两张,每一局会在剩下的牌中摸一张,选择要或不要。要的话就需要打出手中13张牌中的一张,不要的话这张牌废弃,并且不会再被摸到
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
int t,s0,num[15][5];
int tmp=0,k=0;
ll dp[130][15];
ll ksm(ll a,ll b)
{
ll res=1;
while(b)
{
if(b&1) res=a*res%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
ll inv(ll x)
{
return ksm(x,mod-2);
}
void init()
{
for(int i=1;i<=123;i++){
ll v=inv(i);
for(int j=0;j<=13;j++){
if(j==1) dp[i][j]=((i-3)*v%mod*(dp[i-1][1]+1)%mod+3*v%mod)%mod;
else dp[i][j]=((i-3*j)*v%mod*(dp[i-1][j]+1)%mod+(dp[i-1][j-2]+1)*3*j%mod*v%mod)%mod;
}
}
return;
}
int main() {
cin>>t;
getchar();
init();
string s;
while(t--){
getline(cin,s);
memset(num,0,sizeof(num));
k=0;
s0=0;
for(int i=0;i<26;i+=2){
int x=s[i]-'0',y;
if(s[i+1]=='m') y=1;
else if(s[i+1]=='p') y=2;
else if(s[i+1]=='s') y=3;
else y=4;
num[x][y]++;
if(num[x][y]==2) k++;
}
s0=13-2*k;
printf("Case #%d: %lld\n",++tmp,dp[123][s0]);
}
}