码迷,mamicode.com
首页 > 其他好文 > 详细

HDU_5602_概率dp

时间:2016-09-21 01:44:08      阅读:157      评论:0      收藏:0      [点我收藏+]

标签:

http://acm.hdu.edu.cn/showproblem.php?pid=5602

 

dp[1][i][j]表示轮到第二个人操作时,第一人总和i,第二人总和j,第一人胜的最小概率(因为每个人都是聪明的,所以选最小)。

dp[0][i][j]表示第一个人操作时,第一个人胜的最大概率。

先算dp[1],然后用dp[1]算dp[0],注意x==y的情况。

 

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int vis[2][35][35] = {0};
double dp[2][35][35];
char a[5];

int cal(char c)
{
    switch(c)
    {
        case A:   return 1;
        case T:
        case J:
        case K:
        case Q:   return 10;
        default:    return c-0;
    }
}

double dfs1(int x,int y)
{
    if(y > 21)  return 1;
    if(vis[1][x][y])    return dp[1][x][y];
    double temp = 0;
    dp[1][x][y] = x>y;
    for(int i = 1;i < 10;i++)   temp += dfs1(x,y+i)/13;
    temp += dfs1(x,y+10)*4/13;
    dp[1][x][y] = min(dp[1][x][y],temp);
    vis[1][x][y] = 1;
    return dp[1][x][y];
}

double dfs0(int x,int y)
{
    if(x > 21)  return 0;
    if(vis[0][x][y])    return dp[0][x][y];
    dp[0][x][y] = dfs1(x,y);
    double temp = 0;
    for(int i = 1;i < 10;i++)    temp += dfs0(x+i,y)/13;
    temp += dfs0(x+10,y)*4/13;
    dp[0][x][y] = max(dp[0][x][y],temp);
    vis[0][x][y] = 1;
    return dp[0][x][y];
}

int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%s",a);
        int first = 0,second = 0;
        first += cal(a[0]);
        first += cal(a[1]);
        second += cal(a[2]);
        second += cal(a[3]);
        double ans = dfs0(first,second);
        if(ans > 0.5)   printf("YES\n");
        else    printf("NO\n");
    }
    return 0;
}

 

HDU_5602_概率dp

标签:

原文地址:http://www.cnblogs.com/zhurb/p/5891145.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!