题目链接:

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

Hearthstone

Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
#### 问题描述
> Hearthstone is an online collectible card game from Blizzard Entertainment. Strategies and luck are the most important factors in this game. When you suffer a desperate situation and your only hope depends on the top of the card deck, and you draw the only card to solve this dilemma. We call this "Shen Chou Gou" in Chinese.
> Now you are asked to calculate the probability to become a "Shen Chou Gou" to kill your enemy in this turn. To simplify this problem, we assume that there are only two kinds of cards, and you don't need to consider the cost of the cards.
>
> - A-Card: If the card deck contains less than two cards, draw all the cards from the card deck; otherwise, draw two cards from the top of the card deck.
> - B-Card: Deal X damage to your enemy.
>
> Note that different B-Cards may have different X values.
> At the beginning, you have no cards in your hands. Your enemy has P Hit Points (HP). The card deck has N A-Cards and M B-Cards. The card deck has been shuffled randomly. At the beginning of your turn, you draw a card from the top of the card deck. You can use all the cards in your hands until you run out of it. Your task is to calculate the probability that you can win in this turn, i.e., can deal at least P damage to your enemy.

输入

The first line is the number of test cases T (T<=10).

Then come three positive integers P (P<=1000), N and M (N+M<=20), representing the enemy’s HP, the number of A-Cards and the number of B-Cards in the card deck, respectively. Next line come M integers representing X (0<X<=1000) values for the B-Cards.

输出

For each test case, output the probability as a reduced fraction (i.e., the greatest common divisor of the numerator and denominator is 1). If the answer is zero (one), you should output 0/1 (1/1) instead.

样例

sample input

2

3 1 2

1 2

3 5 10

1 1 1 1 1 1 1 1 1 1

sample output

1/3

46/273

题意

对手的血量为p,你有奥术牌n张,火球牌m张,一开始你可以任抽一张牌,之后如果抽到奥术,你就还可以抽两张牌,如果抽到火球,你就能给对手ai点伤害。

问最后打死对手的概率。

题解

我们可以先考虑从n+m张牌中恰好抽出k张奥术的概率,然后再去考虑用k+1张火球打死对手的概率。

队友用O(1<<(n+m))的复杂度强行模拟了牌堆取数的情况。orzorzorz

代码

#include<map>
#include<cmath>
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
#define X first
#define Y second
#define mkp make_pair
#define lson (o<<1)
#define rson ((o<<1)|1)
#define mid (l+(r-l)/2)
#define sz() size()
#define pb(v) push_back(v)
#define all(o) (o).begin(),(o).end()
#define clr(a,v) memset(a,v,sizeof(a))
#define bug(a) cout<<#a<<" = "<<a<<endl
#define rep(i,a,b) for(int i=(a);i<(b);i++) typedef long long LL;
typedef vector<int> VI;
typedef pair<int,int> PII;
typedef vector<pair<int,int> > VPII; const int INF=1e9;
const LL INFL=0x3f3f3f3f3f3f3f3fLL;
const double eps=1e-8; //start---------------------------------------------------------------------- const int maxm=22;
const int maxn=22;
int hp,n,m; int arr[maxn];
LL sumao[maxn];
LL sumhuo[maxn];
LL one[(1<<maxn)+10];
LL cntao,cnthuo[maxn]; LL gcd(LL a,LL b) {
return b==0?a:gcd(b,a%b);
} void init() {
cntao=0;
clr(cnthuo,0);
clr(sumao,0);
clr(sumhuo,0);
} struct Fenshu {
LL a,b;
Fenshu(LL a,LL b):a(a),b(b) {}
Fenshu() {
a=0;
b=1;
}
}; Fenshu add(Fenshu fs1,Fenshu fs2) {
LL ta=fs1.a*fs2.b+fs1.b*fs2.a;
LL tb=fs1.b*fs2.b;
LL g=gcd(ta,tb);
return Fenshu(ta/g,tb/g);
}
Fenshu mul(Fenshu fs1,Fenshu fs2) {
LL ta=fs1.a*fs2.a;
LL tb=fs1.b*fs2.b;
LL g=gcd(ta,tb);
return Fenshu(ta/g,tb/g);
} void pre() {
clr(one,0);
rep(i,0,(1<<(maxm))) {
rep(j,0,maxm) {
if(i&(1<<j)) one[i]++;
}
}
} int main() {
pre();
int tc;
scanf("%d",&tc);
while(tc--) {
init();
scanf("%d%d%d",&hp,&n,&m);
rep(i,0,m) scanf("%d",arr+i);
//从n+m张牌中恰好能取出k张奥术的总数,存在sumao[k]里面。
rep(i,0,1<<(n+m)) {
if(one[i]!=n) continue;
cntao++;
int cnt=1,sum=0;
for(int j=0; cnt&&j<(n+m); j++) {
cnt--;
if(i&(1<<j)) {
sum++;
cnt+=2; }
}
sumao[sum]++;
}
//从m张火球中取出k张并且打死对手的总数,存在sumhuo[k]里面。
rep(i,0,1<<m) {
int cnt=0,sum=0;
rep(j,0,m) {
if(i&(1<<j)) {
cnt++;
sum+=arr[j];
}
}
cnthuo[cnt]++;
if(sum>=hp) {
sumhuo[cnt]++;
}
}
Fenshu ans;
rep(i,0,n+1) {
//i张奥术能让我们抽i+1张火球。
Fenshu tmp;
if(i<m) tmp=mul(Fenshu(sumao[i],cntao),Fenshu(sumhuo[i+1],cnthuo[i+1]));
//最多只能抽到m张火球
else tmp=mul(Fenshu(sumao[i],cntao),Fenshu(sumhuo[m],cnthuo[m]));
ans=add(ans,tmp);
}
printf("%lld/%lld\n",ans.a,ans.b);
}
return 0;
} //end-----------------------------------------------------------------------

HDU 5816 Hearthstone 概率dp的更多相关文章

  1. HDU 3853LOOPS(简单概率DP)

    HDU 3853    LOOPS 题目大意是说人现在在1,1,需要走到N,N,每次有p1的可能在元位置不变,p2的可能走到右边一格,有p3的可能走到下面一格,问从起点走到终点的期望值 这是弱菜做的第 ...

  2. HDU - 1099 - Lottery - 概率dp

    http://acm.hdu.edu.cn/showproblem.php?pid=1099 最最简单的概率dp,完全是等概率转移. 设dp[i]为已有i张票,还需要抽几次才能集齐的期望. 那么dp[ ...

  3. HDU 4405 【概率dp】

    题意: 飞行棋,从0出发要求到n或者大于n的步数的期望.每一步可以投一下筛子,前进相应的步数,筛子是常见的6面筛子. 但是有些地方可以从a飞到大于a的b,并且保证每个a只能对应一个b,而且可以连续飞, ...

  4. HDU 4576 Robot(概率dp)

    题目 /*********************复制来的大致题意********************** 有N个数字,M个操作, 区间L, R. 然后问经过M个操作后落在[L, R]的概率. * ...

  5. HDU 4599 Dice (概率DP+数学+快速幂)

    题意:给定三个表达式,问你求出最小的m1,m2,满足G(m1) >= F(n), G(m2) >= G(n). 析:这个题是一个概率DP,但是并没有那么简单,运算过程很麻烦. 先分析F(n ...

  6. [HDU 4089]Activation[概率DP]

    题意: 有n个人排队等着在官网上激活游戏.Tomato排在第m个. 对于队列中的第一个人.有以下情况: 1.激活失败,留在队列中等待下一次激活(概率为p1) 2.失去连接,出队列,然后排在队列的最后( ...

  7. hdu 3853 LOOPS 概率DP

    简单的概率DP入门题 代码如下: #include<iostream> #include<stdio.h> #include<algorithm> #include ...

  8. HDU 3853 期望概率DP

    期望概率DP简单题 从[1,1]点走到[r,c]点,每走一步的代价为2 给出每一个点走相邻位置的概率,共3中方向,不动: [x,y]->[x][y]=p[x][y][0] ,  右移:[x][y ...

  9. HDU 3366 Passage (概率DP)

    题意:T组测试数据,一个人困在了城堡中,有n个通道,m百万money ,每个通道能直接逃出去的概率为 P[i] ,遇到士兵的概率为 q[i], 遇到士兵得给1百万money,否则会被杀掉,还有 1-p ...

随机推荐

  1. axios和ajax,fetch的区别

    1,传统 Ajax 指的是 XMLHttpRequest(XHR), 最早出现的发送后端请求技术,隶属于原始js中,核心使用XMLHttpRequest对象,多个请求之间如果有先后关系的话,就会出现回 ...

  2. 常用的JavaScript设计模式(二)Factory(工厂)模式

    Factory通过提供一个通用的接口来创建对象,同时,我们还可以指定我们想要创建的对象实例的类型. 假设现在有一个汽车工厂VehicleFactory,支持创建Car和Truck类型的对象实例,现在需 ...

  3. Centos7 安装ipython 和 ipython3

    [root@localhost ~]# wget https://pypi.python.org/packages/79/63/b671fc2bf0051739e87a7478a207bbeb45cf ...

  4. PHP读取excel

    $file = '';//文件名称 $file_ext = explode('.',$file);$file_ext = $file_ext[1];$data['file_ext'] = $file_ ...

  5. STM32(11)——DMA

    简介: DMA:Direct Memory Access,直接存储器访问.DMA传输数据从一个地址空间复制到另外一个地址空间.当CPU初始化这个传输动作,传输动作本身就是DMA控制器来实现和完成.典型 ...

  6. 『Python基础-11』集合 (set)

    # 『Python基础-11』集合 (set) 目录: 集合的基本知识 集合的创建 访问集合里的值 向集合set增加元素 移除集合中的元素 集合set的运算 1. 集合的基本知识 集合(set)是一个 ...

  7. MATLAB数学实验总结

    L1 MATLAB 基础知识 P6 表1-3 数据显示格式 format rat format long P20 表2-5 常用的矩阵函数 zeros(m,n) %零阵 eye(n) %单位阵 one ...

  8. Java基础之instanceof和transient关键字用法

    instanceof 用于检测指定对象是否是某个类(本类.父类.子类.接口)的实例.Java中的instanceof也称为类型比较运算符,因为它将类型与实例进行比较. 返回true或false. 如果 ...

  9. sublime_text3常用操作与快捷键

    1.编辑多列 按鼠标滚轮进行多列选中 键盘ctrl+alt+↓进行多行选中操作 2.快捷键 ctrl+H:替换(F为经典的搜索) ctrl+G:跳到指定行 ctrl+D:选词,连续按选中下面匹配的词, ...

  10. OracleLinux上安装数据库(DBCA)

    磨砺技术珠矶,践行数据之道,追求卓越价值 回到上一级页面: PostgreSQL杂记页     回到顶级页面:PostgreSQL索引页 [作者 高健@博客园  luckyjackgao@gmail. ...