HDU5602 Black Jack DP

Black Jack

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others)
Total Submission(s): 370    Accepted Submission(s): 103


Problem Description
21 point,also named Black Jack, originated in France,has spread around the world.

21 point, a gambling game played by using poker,is also the only one which is able to win banker by using probability calculation.

--- Encyclopedia from good search

We define blackjack rules are as follows, which is different from the original rules slightly.

cards are as follows:

A 2 3 4 5 6 7 8 9 10 J Q K

A is as 1 point.

JQK are all as 10 points.

We assume that the casino prepared a lot of cards,that is, you can assume that the probability of getting each card is the same.

There are two players who were banker and Player.

They get two cards at first and can see the card each other.

Player operates first.

Every turn, he can bid or stop bidding.

If he bid, he can take a card from the deck.

Once the the points are over 21,he will lose at once,which is called "busting", otherwise he will bid until stopping bidding and turn to banker.

the rule of banker is the same as the player's.

If there is no "busting", the one who have higher points win.

If they have the same points,they get the tie.

Here is the task,we give you the cards that both people have gotten.

please judge whether the Player have more than 50% winning percentage,
if yes, output "YES", otherwise output,"NO".

Oh, yes, everyone is very smart.
 

Input
The first line of the input file contains an integer Test(Test<=100000), which indicates the number of test cases.

For each test case, there is a string with four characters. the first and the second char indicate the card of the player.and the others indicate the banker's.(we use ‘T’ instead of '10')
 

Output
For each case of data output "YES" or "NO", it indicates whether the Player have more than 50% winning percentage.
 

Sample Input
  
  
1 TTT9
 

Sample Output
  
  
YES //it's clear that player will not bid, then the blanker has only 2/13 winning percentage.
 

Source
 


题意:闲家和庄家玩牌,每人先摸两张,然后先轮到闲家叫牌摸还是不摸,开到自己不想开为止,超过21点就爆掉。两人分数相同时算平局。闲家弄完再轮到庄家然后再闲家……最后比大小。现在告诉你初始的四张牌是什么,问闲家胜率是否大于50%。

思路:我之前题意理解错了,注意一句话:otherwise he will bid until stopping bidding and turn to banker.一个人可以一直叫到不想叫为止。这里用dp做,dp1[i][j]代表轮到庄家时,在牌面是闲家i庄家j的时候的不输的概率(1-dp1[i][j]就是闲家胜的概率),然后dp2[i][j]代表轮到闲家,牌面是ij时闲家胜的概率


#include <iostream>
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <string>
#include <string.h>
#include <algorithm>
#include <vector>
#include <queue>
#include <iomanip>
#include <time.h>
#include <set>
#include <map>
#include <stack>
using namespace std;
typedef long long LL;
const int INF=0x7fffffff;
const int MAX_N=10000;

int T,a,b;
char s[5];

double dp1[100][100];//闲家点数为i,庄家为j,轮到庄家叫点时,庄家胜的概率
double dp2[100][100];//闲家点数为i,庄家为j,轮到闲家叫点时,闲家胜的概率


void solve(){
    memset(dp1,0,sizeof(dp1));
    memset(dp2,0,sizeof(dp2));
    //庄家
        for(int i=21;i>=2;i--){
            for(int j=21;j>=2;j--){
                if(i<=j){
                    dp1[i][j]=1;
                    continue;
                }
                for(int k=1;k<=13;k++){
                    int t=k;
                    if(k>=10)t=10;
                    dp1[i][j]+=dp1[i][j+t]/13;
                }

            }
        }

        //闲家
        for(int i=21;i>=2;i--){
            for(int j=21;j>=2;j--){
                for(int k=1;k<=13;k++){
                    int t=k;
                    if(t>10)t=10;
                    dp2[i][j]+=dp2[i+t][j]/13;
                }
                dp2[i][j]=max(dp2[i][j],1-dp1[i][j]);
            }
        }
}
int main(){
    solve();
    cin>>T;
    while(T--){
        a=0;b=0;
        scanf("%s",s);
        for(int i=0;i<2;i++){
            if(s[i]=='A')a+=1;
            else if(s[i]=='J'||s[i]=='T'||s[i]=='Q'||s[i]=='K')a+=10;
            else a+=s[i]-'0';
        }
        for(int i=2;i<4;i++){
            if(s[i]=='A')b+=1;
             else if(s[i]=='J'||s[i]=='T'||s[i]=='Q'||s[i]=='K')b+=10;
            else b+=s[i]-'0';
        }



        //cout<<a<<" "<<b<<" "<<dp2[a][b]<<endl;
        if(dp2[a][b]>0.5)cout<<"YES"<<endl;
        else cout<<"NO"<<endl;


    }
    return 0;
}


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值