单人纸牌_NOI导刊2011提高(04)
题目描述
单人纸牌游戏,共36张牌分成9叠,每叠4张牌面向上。每次,游戏者可以从某两个不同的牌堆最顶上取出两张牌面相同的牌(如黑桃10和梅花10)并且一起拿走。如果最后所有纸牌都被取走,则游戏者就赢了,否则游戏者就输了。
George很热衷于玩这个游戏,但是一旦有时有多种选择的方法,George就不知道取哪一种好了,George会从中随机地选择一种走,例如:顶上的9张牌为KS,KH,KD,9H,8S,8D,7C,7D,6H,显然有5种取法:(KS,KH),(KS,KD),(KH,KD),(8S,8D),(7C,7D),当然George取到每一种取法的概率都是1/5。
有一次,George的朋友Andrew告诉他,这样做是很愚蠢的,不过George不相信,他认为如此玩最后成功的概率是非常大的。请写一个程序帮助George证明他的结论:计算按照他的策略,最后胜利的概率。 【输入数据】
9行,每行4组用空格分开的字串,每个字串两个字符,分别表示牌面和花色,按照从堆底到堆顶的顺序给出。
输入输出格式
输入格式:
9行,每行4组用空格分开的字串,每个字串两个字符,分别表示牌面和花色,按照从堆底到堆顶的顺序给出。
输出格式:
一行,最后胜利的概率,精确到小数点后6位。
输入输出样例
输入样例#1:
AS 9S 6C KS JC QH AC KH 7S QD JD KD QS TS JS 9H 6D TD AD 8S QC TH KC 8D 8C 9D TC 7C 9C 7H JH 7D 8H 6S AH 6H
输出样例#1:
0.589314
概率dp.
f[][][][][][][][][]表示当前状态(每一堆的牌数)的概率
从f[0][0][0][0][0][0][0][0][0]=1开始,
每次在当前状态枚举往上放哪两张牌,方法数为cnt,当前概率为p
则把所有放上两张牌的状态f+=p/cnt;
为了方便,此处用数组循环。
由于状态太多,此处不好列出转移方程,请看代码。
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 #include<cstdio> 5 using namespace std; 6 int x,y,cnt,i[11]; 7 double f[5][5][5][5][5][5][5][5][5]; 8 char a[1001][10]; 9 int main() 10 { 11 for (x=1;x<=9;x++) 12 { 13 char s[15]; 14 gets(s+1); 15 a[x][1]=s[10]; 16 a[x][2]=s[7]; 17 a[x][3]=s[4]; 18 a[x][4]=s[1]; 19 } 20 f[0][0][0][0][0][0][0][0][0]=1; 21 for (i[1]=0;i[1]<=4;i[1]++) 22 { 23 for (i[2]=0;i[2]<=4;i[2]++) 24 { 25 for (i[3]=0;i[3]<=4;i[3]++) 26 { 27 for (i[4]=0;i[4]<=4;i[4]++) 28 { 29 for (i[5]=0;i[5]<=4;i[5]++) 30 { 31 for (i[6]=0;i[6]<=4;i[6]++) 32 { 33 for (i[7]=0;i[7]<=4;i[7]++) 34 { 35 for (i[8]=0;i[8]<=4;i[8]++) 36 { 37 for (i[9]=0;i[9]<=4;i[9]++) 38 if (f[i[1]][i[2]][i[3]][i[4]][i[5]][i[6]][i[7]][i[8]][i[9]]) 39 {double p=f[i[1]][i[2]][i[3]][i[4]][i[5]][i[6]][i[7]][i[8]][i[9]]; 40 cnt=0; 41 for (x=1;x<9;x++) 42 for (y=x+1;y<=9;y++) 43 if (i[x]+1<=4&&i[y]+1<=4&&a[x][i[x]+1]==a[y][i[y]+1]) 44 cnt++; 45 if (cnt>0) 46 for (x=1;x<9;x++) 47 for (y=x+1;y<=9;y++) 48 if (i[x]+1<=4&&i[y]+1<=4&&a[x][i[x]+1]==a[y][i[y]+1]) 49 { 50 i[x]++;i[y]++; 51 f[i[1]][i[2]][i[3]][i[4]][i[5]][i[6]][i[7]][i[8]][i[9]]+=p/(double)(cnt*1.0); 52 i[x]--;i[y]--; 53 } 54 } 55 } 56 } 57 } 58 } 59 } 60 } 61 } 62 } 63 printf("%.6lf",f[4][4][4][4][4][4][4][4][4]); 64 }