题目大意:36张牌分成9堆,每堆4张牌,你每次可以任取两堆顶部的牌,但这两张牌点数必须相同。求把所有的牌都拿走的概率。
可以用dfs的方法模拟抽牌过程。我们定义状态为“每堆牌剩余数量的集合”,由于重复状态较多,而且总状态数较少(\(5^9\)),所以可以用dp的思想,记忆化搜索。
我们可以用5进制来记录某种状态:
这个地方我们只需要记录第一个字符即可,所以第二个字符不用要
%*c是输入字符但是忽略字符 ---奇怪的知识又增加了.
因为我们是多组输入所以:
scanf()也有返回值 成功输入是1, 不在输入就退出呗.----奇怪的知识又又增加了.
double ans[maxn];
char a[10][5];
int d[9];
double solve()
{
int x=0;
for(int i=0;i<9;i++){
x=x*5+d[i];///shuomingyizhongzhuangtai
}
if(ans[x]>=0){
return ans[x];
}
int cnt=0;double sum=0;
for(int i=0;i<9;i++){
for(int j=i+1;j<9;j++){
if(d[i]&&d[j]&&a[i][d[i]]==a[j][d[j]]){
d[i]--;d[j]--;
sum+=solve();
d[i]++;d[j]++;
cnt++;
}
}
}
return ans[x]=cnt?sum*1.0/cnt:0;
}
int main()
{
ll t = 1;
///scanf("%lld",&t);
while(t)
{
fill(ans,ans+maxn,-1);
fill(d,d+9,4);
ans[0]=1;
for(int i=0; i<9; ++i){
for(int j=1; j<=4; ++j)
if(scanf(" %c%*c",&a[i][j])!=1)
return 0;
}
printf("%f\n",solve());
}
return 0;
}
原文:https://www.cnblogs.com/KingZhang/p/14883214.html