关闭

HDU 5816 Hearthstone(状压DP)

211人阅读 评论(0) 收藏 举报
分类:

Description
有一个卡组,有两种卡牌,A牌n张,B牌m张,抽到一张A牌可以从卡组中再抽两张,抽到一张B牌可以给敌人造成一定的伤害,现在告诉敌人的血量P以及m张B牌的伤害值,初始状态可以从卡组中拿一张牌,问有多大概率可以打败敌人(即抽到牌的总伤害值大于等于敌人的血量)
Input
第一行一整数T表示用例组数,每组用例首先输入三个整数p,n,m分别表示敌人血量,A牌数,B牌数,之后m个整数ai表示第i张B牌的伤害值
(T<=10,p<=1000,n+m<=20,0< ai<=1000)
Output
对于每组用例,输出打败敌人的概率(输出最简分数形式)
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
Solution
因为最多20张牌,所以想到用一个20位二进制数表示一个状态,用dp[i]表示拿到牌的状态为i是否合法,初始化就是dp[1<< i]=1,i=0,1,…,n+m-1,对于一个状态i,如果已经拿到x张A牌和y张B牌,统计这y张B牌的总伤害,如果大于等于p则后面的牌随意排列都可以打败敌人,那么对答案的贡献就是dp[i]*(n+m-x-y)!,之后通过判断这个状态是否可以继续拿牌来转移到下一个状态,x张A牌可以拿2x张牌,去掉初始手中的一张牌,故若2x-x-y+1>0说明该状态可以接着拿牌,进而枚举这个状态中0的位赋为1即转移到一下状态
Code

#include<cstdio>
#include<iostream>
#include<cstring>
#include<algorithm>
using namespace std;
typedef long long ll;
#define maxn ((1<<20)+11)
ll f[maxn];
int cnt[maxn];
ll gcd(ll a,ll b)
{
    return b?gcd(b,a%b):a;
}
void init()
{
    f[0]=1;
    for(int i=1;i<=20;i++)f[i]=1ll*i*f[i-1];
    for(int i=0;i<(1<<20);i++)
    {
        cnt[i]=0;
        for(int j=0;j<20;j++)
            if(i&(1<<j))cnt[i]++;
    }
}
int T,p,n,m,v[22];
ll dp[maxn];
bool check(int x)
{
    int ans=0;
    for(int i=n;i<n+m;i++)
        if(x&(1<<i))ans+=v[i-n];
    if(ans>=p)return 1;
    return 0;
}
int main()
{
    init();
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d%d",&p,&n,&m);
        for(int i=0;i<m;i++)scanf("%d",&v[i]);
        memset(dp,0,sizeof(dp));
        for(int i=0;i<n+m;i++)dp[1<<i]=1;
        ll ans=0,N=1<<(n+m);
        for(int i=0;i<N;i++)
        {
            int tot=cnt[i],x=cnt[i&((1<<n)-1)],y=tot-x;
            if(check(i))
            {
                ans+=dp[i]*f[n+m-tot];
                continue;
            }
            if(x-y+1<=0)continue;
            for(int j=0;j<n+m;j++)
                if(!(i&(1<<j)))dp[i|(1<<j)]+=dp[i];
        }
        ll g=gcd(ans,f[n+m]);
        printf("%I64d/%I64d\n",ans/g,f[n+m]/g);
    }
}
0
0
查看评论

HDU 5816 Hearthstone (状压dp)

题目大概说有两种卡牌,使用A牌能从牌堆摸两张牌,使用B牌能对对方造成xi点伤害。在你的回合,你从牌堆摸一张牌,问能对对方造成p点及以上伤害的概率。 要求的其实就是能造成p点以上伤害的牌堆排列数/牌堆全排列数。 全排列而且总数为20,这种就该想到尝试用状压DP。。 dp[S]表示已经摸的牌的...
  • Ezereal
  • Ezereal
  • 2016-08-10 09:34
  • 288

hdu 5816 Hearthstone (状压dp)

比赛的时候没想出来.. 题意:给p,n,m三个数,分别表示敌人的血量,可抽A牌的数量(A牌可以再抽两张),可抽B牌的数量(B牌对敌人造成a[i]点伤害),问现在轮到我抽一张牌(抽了A牌后又可以抽2张,如此往复),问最后打死敌人的概率。 样例:第一组:5/15(只能从15张牌里先取1张A牌才能获胜) ...
  • TheHide
  • TheHide
  • 2016-08-10 20:42
  • 407

HDU - 5816 Hearthstone 状压DP + 组合计数

传送门:HDU5816 题意:牌堆里有两种卡牌,使用A牌能从牌堆摸2张牌,使用B牌能对对方造成 b[i] 点伤害。开始的时候从牌堆摸一张牌,问你能对敌方造成p点或以上伤害的概率是多少。  首先要注意计算所有的可能手牌状态,假设抽到过x张A牌,那么手里最多有x+1张B牌,并且当手里有x+...
  • lxy767087094
  • lxy767087094
  • 2017-09-06 18:04
  • 92

HDU 4856 Tunnels(BFS+状压DP)

HDU 4856 Tunnels 题目链接 题意:给定一些管道,然后管道之间走是不用时间的,陆地上有障碍,陆地上走一步花费时间1,求遍历所有管道需要的最短时间,每个管道只能走一次 思路:先BFS预处理出两两管道的距离,然后状态压缩DP求解,dp[s][i]表示状态s,停在管道i时候的最小花费 ...
  • u011217342
  • u011217342
  • 2014-07-08 22:47
  • 1029

HDU 6086 AC自动机+状压dp

题意:题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6086 给出m个单词,要构造出长度为2*L的包含这全部m个单词的字符串,并且保证这个字符串非对称,其中字符只包括0和1,问一共有多少种构造方法。思路:本题是hdu2825的拓展,建议先做2825,...
  • Bahuia
  • Bahuia
  • 2017-08-13 19:48
  • 469

HDU 6149 状压dp

9##题意: 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6149 中文题。思路:状态压缩,将高点的选择情况压位。dp[i][S]表示的是枚举到第i个低点,且当前选择高点状态为S的最大山谷数。转移简单,注意细节。代码:#include <b...
  • Bahuia
  • Bahuia
  • 2017-08-20 22:23
  • 241

HDU 5816 状压dp

Hearthstone Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others) Problem Description Hearthstone ...
  • black_miracle
  • black_miracle
  • 2016-08-09 20:18
  • 129

hdu 5816 Hearthstone 状压DP+记忆化搜索

???
  • vvv_557
  • vvv_557
  • 2017-07-15 10:45
  • 67

[HDU 5816] Hearthstone (概率DP+状压)

HDU - 5816 牌堆里有 NN张 A类卡,MM张 B类卡 A类卡能让你从牌堆里抽两张卡 第 ii张 B类卡能让你对对手造成 xix_i点伤害 刚开始从牌堆抽 1张牌,并且对手有 PP点生命值 问一回合内打倒对手的概率是多少 赛后看了下题解,感谢出题人让我 (N2N...
  • u012015746
  • u012015746
  • 2016-08-09 19:53
  • 739

HDU6006 - (预处理+状压dp)

没写出来的原因多半是平时自己练太少了,其实很水的一个状压题解:预处理出每个地方可以有哪些人组合完成 dp[i][j]就表示前i个人在状态j的最大完成数量。#include <iostream> #include <cstring> #include <string&g...
  • yxm980918
  • yxm980918
  • 2017-08-28 21:24
  • 157
    个人资料
    • 访问:545747次
    • 积分:24318
    • 等级:
    • 排名:第322名
    • 原创:1930篇
    • 转载:0篇
    • 译文:0篇
    • 评论:68条
    最新评论