UVA 1637 Double Patience 概率DP


Double Patience

Time Limit: 3000MS   Memory Limit: Unknown   64bit IO Format: %lld & %llu

Submit Status

Description

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

Source

Root :: AOAPC II: Beginning Algorithm Contests (Second Edition) (Rujia Liu) :: Chapter 10. Maths :: Examples

Submit Status

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;

double dp[5][5][5][5][5][5][5][5][5];
bool vis[5][5][5][5][5][5][5][5][5];
char dui[10][5];

char str[4][5];

double dfs(int w1,int w2,int w3,int w4,int w5,int w6,int w7,int w8,int w9)
{
    if(vis[w1][w2][w3][w4][w5][w6][w7][w8][w9])
        return dp[w1][w2][w3][w4][w5][w6][w7][w8][w9];
    vis[w1][w2][w3][w4][w5][w6][w7][w8][w9]=true;
    double& x =dp[w1][w2][w3][w4][w5][w6][w7][w8][w9];
    bool flag=false;
    int top[10]={w1,w2,w3,w4,w5,w6,w7,w8,w9};
    for(int i=0;i<9;i++)
        if(top[i]) {flag=true; break;}
    if(flag==false)
    {
        return x=1.0;
    }

    int qu=0;
    double sum=0.0;
    for(int i=0;i<9;i++)
    {
        if(top[i]!=0)
        for(int j=i+1;j<9;j++)
        {
            if(top[j]==0) continue;
            if(dui[i][top[i]]==dui[j][top[j]])
            {
                top[i]--; top[j]--;
                qu++;
                sum+=dfs(top[0],top[1],top[2],top[3],top[4],top[5],top[6],top[7],top[8]);
                top[i]++; top[j]++;
            }
        }
    }
    if(sum>0) x=sum/(1.*qu);
    return x;
}

int main()
{
	while(scanf("%s%s%s%s",str[0],str[1],str[2],str[3])!=EOF)
	{
	    memset(dp,0,sizeof(dp));
	    memset(vis,0,sizeof(vis));

		for(int i=0;i<4;i++)
			dui[0][i+1]=str[i][0];
		for(int i=0;i<8;i++)
		{
			scanf("%s%s%s%s",str[0],str[1],str[2],str[3]);
			for(int j=0;j<4;j++)
				dui[i+1][j+1]=str[j][0];
		}
		dfs(4,4,4,4,4,4,4,4,4);
		printf("%.6lf\n",dp[4][4][4][4][4][4][4][4][4]);
	}
	return 0;
}
时间: 2024-08-07 17:28:10

UVA 1637 Double Patience 概率DP的相关文章

uva 1637 Double Patience

https://vjudge.net/problem/UVA-1637 36张牌分成9堆,每堆4张牌.每次可以拿走某两堆顶部的牌,但需要点数相同. 如果有多种拿法则等概率的随机拿. 如果最后拿完所有牌则游戏成功.按顺序给出每堆牌的4张牌,求成功概率. #include<cstdio> using namespace std; char s[10][5]; char ss[5]; int left[10]; int v[2000001]; double dp[2000001]; int t; i

1637 - Double Patience(状态转移+求成功概率)

用九元组表示当前状态,即每队牌剩的张数,状态总数为5^9=1953125. 设d[ i ]表示状态i对应的成功概率,则根据全概率公式,d[ i ]为后继成功概率的平均值,按照动态规划的写法计算即可. 这个动态规划我不会写,帅哥思路真的很清晰很好啊. 但是学会还是很高兴的 #include<cstdio> #include<vector> #include<cstring> #include<algorithm> using namespace std; #d

1637 - Double Patience (概率DP)

一道状态较多的概率DP,想要表示所有的状态显然要拓展几个维度表示九堆牌当前的状态 . 但是这么写太复杂,所以我们不妨用一个vector来储存状态,将dp数组用一个map来表示,即 map<vector<int> ,double> d; 利用vector可以作为函数参数传递这个优点,将大大节省代码量 . 概率很好求,在每一次迭代中,寻找所有可以转移的状态数tot,那么状态转移就是d[i] = sum(d[i-1])/tot . 也就是全概率公式 . 递归边界是当所有牌都被摸走了,返回

UVA 10529 Dumb Bones 概率dp 求期望

题目链接:点击打开链接 题意: 要在一条直线上摆多米诺骨牌. 输入n, l, r 要摆n张排,每次摆下去向左倒的概率是l, 向右倒的概率是r 可以采取最优策略,即可以中间放一段,然后左右两边放一段等,摆放顺序任意. 问:在最佳策略下要摆成n张牌的期望次数. 思路: 点击打开链接 #include <cstdio> #include <iostream> #include <cstring> #include <queue> #include <algo

UVA 10529 - Dumb Bones (概率dp)

题目描述 You are trying to set up a straight line of dominos, standing on end, to be pushed over later for your entertainment. (Sure, it seems pointless to set something up only to knock it down again, but you have some strange hobbies) The tricky thing

UVA 10529-Dumb Bones(概率dp)

题意: 给出放一个多米诺骨牌,向左向右倒的概率,求要放好n个骨牌,需要放置的骨牌的期望次数. 分析: 用到区间dp的思想,如果一个位置的左面右面骨牌都已放好,考虑,放中间的情况, dp[i]表示放好前i个骨牌,要放的期望次数,枚举1-i,每个点做中间点求对应的期望,取最小值. dp[i]=min(L*dp[l]+R*dp[r]+1/(1.0-L-R)); #include <map> #include <set> #include <list> #include <

UVa 11468 (AC自动机 概率DP) Substring

将K个模板串构成一个AC自动机,那些能匹配到的单词节点都称之为禁止节点. 然后问题就变成了在Tire树上走L步且不经过禁止节点的概率. 根据全概率公式用记忆化搜索求解. 1 #include <cstdio> 2 #include <cstring> 3 #include <queue> 4 using namespace std; 5 6 const int maxnode = 500; 7 const int sigma_size = 64; 8 int idx[2

uva 12723 概率dp

Dudu is a very starving possum. He currently stands in the first shelf of a fridge. This fridge iscomposed of N shelves, and each shelf has a number Qi (1 ≤ i ≤ N) of food. The top shelf, whereDudu is, is identified by the number 1, and the lowest is

UVa 10828 Back to Kernighan-Ritchie 高斯消元+概率DP

题目来源:UVa 10828 Back to Kernighan-Ritchie 题意:从1开始 每次等概率从一个点到和他相邻的点 有向 走到不能走停止 求停止时每个点的期望 思路:写出方程消元 方程有唯一解 多解 无解的情况 有环 一直再环里无法停止算无穷大 从1不能到的点期望为0 #include <cstdio> #include <cstring> #include <algorithm> #include <vector> #include <