UVALive 6624 - Card Trick - 概率dp

来源:互联网 发布:网络传输异常 编辑:程序博客网 时间:2024/05/16 17:52

题意:有很多张牌,当翻开一张数值是x,那就再翻这张牌后面的第x张,直到翻到一张他后面的第x张不存在,给出一个人翻牌的起始位置,翻的n张牌,问第二个人从前十张任意一张开始翻,结束位置和第一个人相同的概率。J,Q,K的值都是10,A是11。

比较水的概率dp,只是一开始没读懂题……从前十个位置开始,那么就是前十个位置的概率初始值为0.1,其余为0,如果第一个人翻开了的位置,那么数字就是确定的了,一定会转移到下一个固定位置,就是第一个翻开的下一个位置,对于其他位置会有4/13的可能前进10步其余可能各1/13。最后输出第一个dp[m],m是第一个翻开的最后一张牌的位置。

#include <iostream>#include <cstring>#include <cstdio>using namespace std;double dp[2000];int id[2000];char s[10];int main() {    int n, m, mx, a, i, j;    while(~scanf("%d%d", &n, &m)) {        memset(dp, 0, sizeof(dp));        memset(id, 0, sizeof(id));        for(i = 0; i < n; i++) {            scanf("%s", s);            if(s[1] != 0 || s[0] > 'A')                a = 10;            else if(s[0] == 'A')                a = 11;            else a = s[0] - '0';            id[m] = a;            m += a;        }        m -= a;        for(i = 1; i < 11; i++)            dp[i] = 0.1;        for(i = 1; i < m; i++) {            if(id[i] != 0) {                dp[i + id[i]] += dp[i];                continue;            }            for(j = 2; j < 12; j++) {                if(j == 10)                    dp[i + j] += dp[i] * 4.0 / 13;                else dp[i + j] += dp[i] * 1.0 / 13;            }        }        printf("%.15lf\n", dp[m]);    }    return 0;}


0 0