洛谷 P1837 单人纸牌
P1837 单人纸牌 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)(逐渐变懒)
(这是我写过最壮观的dp)
这个题其实不难,但是设计状态需要一定的胆量(?
我们设计dp[a][b][c][d][e][f][g][h][i]表示九叠牌分别被取走abcdefghi张时的概率
再开一个sz[i][j]数组用来存第i叠的第j个数字(注意牌的输入顺序是从下往上)
然后就直接暴力转移,(注意在转移之前要先跑一遍一共有多少对牌可以取,记录在sum里,因为George是等概率取,所以到达下面每一个状态的概率是现在的概率*1/sum)
然后就没有了……(这是个设计状态需要勇气但写起来一点都不难的dp)
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
char s[1005];
char sz[10][5];
double ans,dp[5][5][5][5][5][5][5][5][5],a;
long long i[10],shu;
int main(){
for(int i=1;i<=9;i++){
gets(s);
sz[i][1]=s[9];
sz[i][2]=s[6];
sz[i][3]=s[3];
sz[i][4]=s[0];
}
dp[0][0][0][0][0][0][0][0][0]=1;
for(i[1]=0;i[1]<=4;i[1]++){
for(i[2]=0;i[2]<=4;i[2]++){
for(i[3]=0;i[3]<=4;i[3]++){
for(i[4]=0;i[4]<=4;i[4]++){
for(i[5]=0;i[5]<=4;i[5]++){
for(i[6]=0;i[6]<=4;i[6]++){
for(i[7]=0;i[7]<=4;i[7]++){
for(i[8]=0;i[8]<=4;i[8]++){
for(i[9]=0;i[9]<=4;i[9]++){
if(dp[i[1]][i[2]][i[3]][i[4]][i[5]][i[6]][i[7]][i[8]][i[9]]!=0){
a=dp[i[1]][i[2]][i[3]][i[4]][i[5]][i[6]][i[7]][i[8]][i[9]];
shu=0;
for(int x=1;x<=9;x++){
for(int y=x+1;y<=9;y++){
if(i[x]+1<=4&&i[y]+1<=4&&sz[x][i[x]+1]==sz[y][i[y]+1]){
shu++;
}
}
}
if(shu!=0){
for(int x=1;x<=9;x++){
for(int y=x+1;y<=9;y++){
if(i[x]+1<=4&&i[y]+1<=4&&sz[x][i[x]+1]==sz[y][i[y]+1]){
i[x]++;
i[y]++;
dp[i[1]][i[2]][i[3]][i[4]][i[5]][i[6]][i[7]][i[8]][i[9]]+=a/(double)(shu*1.0);
i[x]--;
i[y]--;
}
}
}
}
}
}
}
}
}
}
}
}
}
}
printf("%.6lf\n",dp[4][4][4][4][4][4][4][4][4]);
return 0;
}

浙公网安备 33010602011771号