uestcoj 890 Card Trick(dp+逆推)

题目链接:

思路:从终点向前递推。

首先p[I]表示从第i个点到终点的概率。则分为两种情况进行考虑。
【1】已经翻到的点则它必定会到终点,则概率为1.
【2】不知道的点则要进行枚举。那么p[i]=sum(p[i+j])/13(2=<j<=13).那么这个问题就解决了。。

为什么要逆推,因为从前往后走,要用到后面的状态。

哎,自己的dp好弱啊,一个暑假好像都没怎么做。。哎,加油啊!!!
题目:

Card Trick

Time Limit: 2999/999MS (Java/Others)     Memory Limit: 65432/65432KB (Java/Others)
 

I am learning magic tricks to impress my girlfriend Alice. My latest trick is a probabilistic one, i.e. it does work in most cases, but not in every case. To perform the trick, I first shuffle a set of many playing cards and put them all in one line with faces up on the table. Then Alice secretly selects one of the first ten cards (i.e. she chooses  x0 , a secret number between  1  and  10  inclusive) and skips cards repeatedly as follows: after having selected a card at position  xi  with a number  c(xi)  on its face, she will select the card at position  xi+1=xi+c(xi) . Jack (J), Queen (Q), and King (K) count as  10 , Ace (A) counts as  11 . You may assume that there are at least ten cards on the table.

Alice stops this procedure as soon as there is no card at position  xi+c(xi) . I then perform the same procedure from a randomly selected starting position that may be different from the position selected by Alice. It turns out that often, I end up at the same position. Alice is very impressed by this trick.

However, I am more interested in the underlying math. Given my randomly selected starting position and the card faces of every selected card (including my final one), can you compute the probability that Alice chose a starting position ending up on the same final card? You may assume that her starting position is randomly chosen with uniform probability (between  1  and  10  inclusive). I forgot to note the cards that I skipped, so these cards are unknown. You may assume that the card face of every single of the unknown cards is independent of the other card faces and random with uniform probability out of the possible card faces (i.e. 2-10JQK, and A).

title

Illustration of first sample input: my starting position is  2 , so I start selecting that card. Then I keep skipping cards depending on the card's face. This process iterates until there are not enough cards to skip (in this sample: Q). The final Q card is followed by  0  to  9  unknown cards, since Q counts as  10 .

Input

For each test case:

  • A line containing two integers  n   (1n100)  and  m  ( 1m10 ) where  n  is the number of selected cards and  m  is the  1 -based position of my first selected card.
  • A line with  n  tokens that specify the  n  selected card faces (in order, including the final card). Each card face is given either as an integer  x  ( 2x10 ) or as a single character (JQK, or A as specified above).

Output

For each test case, print one line containing the probability that Alice chooses a starting position that leads to the same final card. Your output should have an absolute error of at most  107 .

Sample input and output

Sample Input Sample Output
5 2
2 3 5 3 Q
1 1
A
1 2
A
1 10
A
6 1
2 2 2 2 2 2
7 1
2 2 2 2 2 2 2
3 10
10 J K
0.4871377757023325348071573
0.1000000000000000000000000
0.1000000000000000000000000
0.1748923357025314239697490
0.5830713210321767445117468
0.6279229611115749556280350
0.3346565827603272001891974

Source

Northwestern European Regional Contest 2013

UESTC Online Judge

Copyright (C) 2014 Ruins He(@lyhypacm), Jianjin Fan(@pfctgeorge) and Yun Li(@mzry1992). Project home

Any Problem, Please Report On Issues Page Or Discuss With Us In Mailing List.

Currently online registered users: 6

代码为:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#include<vector>
#include<cmath>
#include<string>
#include<queue>
#define eps 1e-9
#define ll long long
#define INF 0x3f3f3f3f
using namespace std;
const int maxn=2000;

double  p[maxn],ans;
int n,m;

int main()
{
    char str[maxn];
    int temp;
    while(~scanf("%d%d",&n,&m))
    {
        memset(p,0,sizeof(p));
        int start=m;
        for(int i=1;i<=n;i++)
        {
            scanf("%s",str);
            p[start]=1;
            if(str[0]<'A'&&str[0]>='2'&&str[0]<='9')  temp=str[0]-'0';
            else if(str[0]=='1'||str[0]=='J'||str[0]=='Q'||str[0]=='K')  temp=10;
            else temp=11;
            start+=temp;
        }
        ans=0;
        for(int i=start;i>=1;i--)
        {
            if(p[i]==0)
            {
                for(int j=2;j<=11;j++)
                {
                   temp=(j==10?4:1);
                   p[i]+=temp*p[i+j];
                }
                p[i]=p[i]/13;
            }
            if(i<=10)  ans+=p[i];
        }
        printf("%.10f\n",ans/10);
    }
    return 0;
}



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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值