题目大意: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