UVALive 6624 Card Trick (概率DP)

33 篇文章 0 订阅

大体题意:

一副扑克牌游戏,你要掀n个扑克牌,每个扑克牌上面有数值大小,这个数值大小x代表你要往后走x步,走到最后一个步就不走了!

另一个人也要玩这个游戏,他的起点是1到10随意挑选一个! 除了第一个翻得牌知道以外,其余都不知道,求第二个人最后的终点和第一个人的终点一样的概率!

思路:

只有13个牌,2~11,  A是11,J Q K 10是10 ,因此翻牌是10的概率是  4/13, 其余的都是1/14.

我们可以根据第一个人翻牌情况 把他们的位置记录下来!然后倒着枚举位置(倒着枚举要好一些 ,因为目标是后面的位置)

然后第二层循环枚举走的步数,令dp[i]表示翻牌第i个位置的牌  能走到终点的概率!

那么显然  ,假设 k 是第一个人的路径,那么dp[k]都是1.0,然后转移方程就是dp[i] += dp[i + j] * p [j];

最后答案就是 dp[1] + dp[2] + ... + dp[10]  这10个起始位置!


#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
char cmd[10];
double dp[1500];
int main(){
    int n,m;
    while(scanf("%d %d",&n,&m) == 2){
        int cur = m;
        memset(dp,0,sizeof dp);
        dp[cur] = 1.0;
        for (int i = 0; i < n; ++i){
            scanf("%s",cmd);
            if (i == n-1)continue;
            char ch1 = cmd[0],ch2 = cmd[1];
            if (ch1 == 'J' || ch1 == 'Q' || ch1 == 'K' || (ch1 == '1' && ch2 == '0'))cur += 10;
            else if (ch1 == 'A') cur += 11;
            else cur += ch1 - 48;
            dp[cur] = 1.0;
        }
        for (int i = cur; i >= 1; --i){
            if (dp[i] == 1.0)continue;
            for (int j = 2; j <= 11; ++j){
                if (j == 10) dp[i] += dp[i+j] * 4.0/13.0;
                else dp[i] += dp[i+j] * 1.0 / 13.0;
            }
        }
        double ans = 0;
        for (int i = 1; i <= 10; ++i)ans += dp[i];
        printf("%.15lf\n",ans/10);
    }
    return 0;
}


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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值