zoukankan      html  css  js  c++  java
  • Gym 101334D 记忆化dp

    大致题意:

    给你9堆扑克牌,每堆牌有4张,大小从A~K。每次从9堆牌牌顶抽走两张大小相同的牌,且抽走每一对相同的牌的概率都相等。问可以全部抽完的概率。

    分析:

    这是一道概率dp题。剩余的牌数作为状态,有9堆,意味着要一个9维数组来存d[i1][i2][i3][i4][i5][i6][i7][i8][i9]表示这个状态的概率,0<=i<=4。

    状态转移:

    当前状态的概率等于抽走两张牌后所能达到的状态的概率和除以所能达到的状态数

    边界d[0][0][0][0][0][0][0][0][0]=1

    #include <bits/stdc++.h>
    using namespace std;
    
    char s[15][10];
    map<vector<int>,double> d;
    
    double dp(vector<int> cnt,int left)
    {
        if(left==0) return 1.0;
        if(d.count(cnt)) return d[cnt];
        d[cnt]=0;
        int tmp=0;
        double res = 0;
        for(int i=1;i<=9;i++)
        {
            if(cnt[i]==0) continue;
            for(int j=i+1;j<=9;j++)
            {
                if(cnt[j]==0) continue;
                if(s[i][cnt[i]]==s[j][cnt[j]])
                {
                    cnt[i]--;
                    cnt[j]--;
                    //debug(cnt);
                    res+=dp(cnt,left-2);
                    cnt[i]++;
                    cnt[j]++;
                    tmp++;
                }
            }
        }
        if(tmp>0)  d[cnt]=res/tmp;
        return d[cnt];
    }
    
    int main()
    {
    //    freopen("in.txt","r",stdin);
        freopen("double.in","r",stdin);
        freopen("double.out","w",stdout);
        char ts[5];
        for(int i=1;i<=9;i++)
        {
            for(int j=1;j<=4;j++)
            {
                scanf("%s",ts);
                s[i][j]=ts[0];
            }
        }
        vector<int> cnt(10,4);
        d.clear();
        printf("%.6f
    ",dp(cnt,36));
        return 0;
    }
  • 相关阅读:
    problem report: middle of linked list
    Partition List解题报告
    Reverse Linked List解题报告
    Remove Duplicates from Sorted List解题报告
    strStr解题报告
    各种编码之间的关系以及getBytes的使用
    jsp/servlet中的编码问题
    javabean+servlet+jsp实现分页
    ligerUI实现分页
    java实现的简单词法分析器
  • 原文地址:https://www.cnblogs.com/pach/p/6979181.html
Copyright © 2011-2022 走看看