uva1637Double Patience

状态压缩,记忆化搜索。

用一个5进制数来表示每堆排到了哪一个位置。和2进制是一样的,不过不能用位运算。

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int maxn = 2000000+10;

double dp[maxn];
bool vis[maxn];
char s[10][10][5];
int v,v2;

double dfs(int n) {
    v++;
    if(n==0) return 1.0;
    if(vis[n]) {v2++; return dp[n];}
    vis[n]=1;

    int tmp=n,cnt=0;
    int a[10];
    for(int i=1;i<=9;i++) {
        a[i]=tmp%5;
        tmp/=5;
    }
    for(int i=1;i<9;i++)
        for(int j=i+1;j<=9;j++)
            if(a[i] && a[j] && s[i][a[i]][0]==s[j][a[j]][0]) {
                tmp=0;
                for(int k=9;k>=1;k--) {
                    tmp*=5;
                    if(k==i || k==j) tmp+=a[k]-1;
                    else tmp+=a[k];
                }
                dp[n]+=dfs(tmp);
                cnt++;
            }
    if(cnt) dp[n]=dp[n]/(1.0*cnt);
    return dp[n];
}

int main() {
    while(scanf("%s",s[1][1])==1) {
        for(int i=2;i<=4;i++) scanf("%s",s[1][i]);
        for(int i=2;i<=9;i++)
        for(int j=1;j<=4;j++)
            scanf("%s",s[i][j]);
        memset(dp,0,sizeof(dp));
        memset(vis,0,sizeof(vis));
        dfs(1953124);
        printf("%.6lf\n",dfs(1953124));
    }
    return 0;
}
时间: 2024-12-17 13:29:50

uva1637Double Patience的相关文章

UVA1637Double Patience(概率 + 记忆化搜索)

训练指南P327 题意:36张牌分成9堆, 每堆4张牌.每次拿走某两堆顶部的牌,但需要点数相同.如果出现多种拿法则等概率的随机拿. 如果最后拿完所有的牌则游戏成功,求成功的概率. 开个9维数组表示每一堆的状态,模拟搜索一下 1 #include <iostream> 2 #include <cstdio> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 const in

``Accordian&#39;&#39; Patience UVA 127

说说: 这道题难度其实并不但,但是比较繁琐,且细节容易被忽略.先分析一下游戏规则吧,知道游戏规则之后,问题自然而然就解决了.首先放着一行52个扑克牌堆(ps:输入的时候分两行输入)开始每堆只有一张牌,然后从左到右开始判断,若一张牌和左边第一张牌或者左边第三张牌的大小或者花色相同,则将该张牌放到那一对牌之上并且要求继续向左匹配,直到不能匹配为止.若某个堆一张牌都不剩了,则该堆不存在了,也就是说如果两堆相邻,则两堆的牌数都不能为0.最后按照这个规则,直到没有牌能够移动位置.(ps:移动是指顶层牌的移

UVa OJ 127 - &quot;Accordian&quot; Patience (“手风琴”纸牌)

UVa OJ 127 - "Accordian" Patience ("手风琴"纸牌) Time limit: 3.000 seconds 限时:3.000秒 Problem 问题 You are to simulate the playing of games of "Accordian" patience, the rules for which are as follows: 模拟玩一个"手风琴"纸牌游戏,规则如下: D

ACM学习历程——UVA 127 &quot;Accordian&quot; Patience(栈;模拟)

Description  ``Accordian'' Patience  You are to simulate the playing of games of ``Accordian'' patience, the rules for which are as follows: Deal cards one by one in a row from left to right, not overlapping. Whenever the card matches its immediate n

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 pile

uva 127 &quot;Accordian&quot; Patience(手风琴纸牌)

用 栈 stack 来处理. 直接根据题目描述写就可以.不要忘记每组数据最后的清空栈堆. 题目大意: 给定52张的扑克牌,现在要求对扑克牌进行整理,对于每一张扑克牌,如果左边的第三张存在那么就去判断这一张是否和第三张满足花色或卡片值相同,如果满足则把这一张移动到左边的第三张,否则去判断左边的第一张是否和这一张满足条件:如果左边的第三张不存在那么只要去判断左边的第一张即可.最后输出剩下的扑克牌的堆数,并且输出每一堆的牌数. #include<stdio.h> #include<iostre

Uva 127 poj 1214 `Accordian&#39;&#39; Patience

 ``Accordian'' Patience  You are to simulate the playing of games of ``Accordian'' patience, the rules for which are as follows: Deal cards one by one in a row from left to right, not overlapping. Whenever the card matches its immediate neighbour on

&quot;Accordian&quot; Patience UVA 127 (”手风琴“牌游戏)

"Accordian" Patience From:UVA, 127 Submit Time Limit: 3000 MS You are to simulate the playing of games of ``Accordian'' patience, the rules for which are as follows: Deal cards one by one in a row from left to right, not overlapping. Whenever th

UVa 127 - &quot;Accordian&quot; Patience POJ 1214 链表题解

UVa和POJ都有这道题. 不同的是UVa要求区分单复数,而POJ不要求. 使用STL做会比较简单,这里纯粹使用指针做了,非常麻烦的指针操作,一不小心就错.调试起来还是非常费力的 本题理解起来也是挺费力的,要搞清楚如何模拟也不容易啊,读题要很仔细. 纯指针的操作挺快的吧.不过POJ 0ms,而UVa就0.2左右了. 三相链表: 1 只要有叠起来的牌,那么就使用一个down指针指向下面的牌就可以了. 2 使用双向链表,可以方便前后遍历. 3 记得有了更新牌之后,又要重新开始检查是否需要更新牌,这是