UVa 1637 Double Patience

42 篇文章 0 订阅
40 篇文章 0 订阅
Double Patience is a single player game played with a standard 36-card deck. The cards are shuffled
and laid down on a table in 9 piles of 4 cards each, faces up.
After the cards are laid down, the player makes turns. In a turn he can take top cards of the same
rank from any two piles and remove them. If there are several possibilities, the player can choose any
one. If all the cards are removed from the table, the player wins the game, if some cards are still on
the table and there are no valid moves, the player loses.
George enjoys playing this patience. But when there are several possibilities to remove two cards,
he doesn’t know which one to choose. George doesn’t want to think much, so in such case he just
chooses a random pair from among the possible variants and removes it. George chooses among all
possible pairs with equal probability.
For example, if the top cards are KS, KH, KD, 9H, 8S, 8D, 7C, 7D, and 6H, he removes any
particular pair of (KS, KH), (KS, KD), (KH, KD), (8S, 8D), and (7C, 7D) with the equal probability
of 1/5.
Once George’s friend Andrew came to see him and noticed that he sometimes doesn’t act optimally.
George argued, that it is not important — the probability of winning any given patience with his
strategy is large enough.
Help George to prove his statement — given the cards on the table in the beginning of the game,
find out what is the probability of George winning the game if he acts as described.
Input
The input file contains several test cases, each of them consists of nine lines. Each line contains the
description of four cards that form a pile in the beginning of the game, from the bottom card to the
top one.
Each card is described with two characters: one for rank, one for suit. Ranks are denoted as ‘6’ for
six, ‘7’ for seven, ‘8’ for eight, ‘9’ for nine, ‘T’ for ten, ‘J’ for jack, ‘Q’ for queen, ‘K’ for king, and ‘A’ for
ace. Suits are denoted as ‘S’ for spades, ‘C’ for clubs, ‘D’ for diamonds, and ‘H’ for hearts. For example,
“KS” denotes the king of spades.
Card descriptions are separated from each other by one space.
Output
For each test case, output a line with one real number — the probability that George wins the game if
he plays randomly. Your answer must be accurate up to 10−6
.
Sample Input
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
Sample Output

0.589314

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

记忆化搜索+状态压缩+字符串~

把每摞牌轮到第几张记为一个5进制的9位数,f[i]表示状态为i时取完的概率,每次搜索取走哪两张牌,如果该状态记录过,直接返回f值。

对于AJQK之类的牌不需要转化为数字,直接用字符比较就可以了。

注意输入是按从下往上输入的!!!我因为这个卡了三天!!!


#include<cstdio>
#include<cstring>

int lo[11],kkzvu;
bool b[2000001];
double f[2000001];
char s[10][5][3];

double findd(int u)
{
	if(b[u]) return f[u];
	b[u]=1;int tot=0,k1,k2;
	if(u==kkzvu) return f[u]=1;
	f[u]=0;
	for(int i=1;i<9;i++)
	  if((k1=(u%lo[i+1])/lo[i])!=4)
	    for(int j=i+1;j<=9;j++)
	      if((k2=(u%lo[j+1])/lo[j])!=4 && s[i][k1+1][0]==s[j][k2+1][0])
	        tot++,f[u]+=findd(u+lo[i]+lo[j]);
	if(!f[u]) return 0;
	return f[u]/=tot;
}

int main()
{
	lo[1]=1;
	for(int i=1;i<=9;i++) lo[i+1]=lo[i]*5,kkzvu+=lo[i]*4;
	while(scanf("%s",s[1][4])!=EOF)
	{
		memset(b,0,sizeof(b));
		for(int i=1;i<=9;i++)
		  for(int j=1;j<=4;j++)
		    if(i!=1 || j!=1) scanf("%s",s[i][5-j]);
		printf("%.6lf\n",findd(0));
	}
	return 0;
}


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值