多校7 HDU5816 Hearthstone 状压DP+全排列
多校7 HDU5816 Hearthstone 状压DP+全排列
题意:boss的PH为p,n张A牌,m张B牌。抽取一张牌,能胜利的概率是多少?
如果抽到的是A牌,当剩余牌的数目不少于2张,再从剩余牌里抽两张,否则全部拿完。
每次拿到一张B牌,对boss伤害B[i]的值
思路:dp[i]表示状态为i时的方案数
先处理出所有状态下的方案,再枚举每种状态,如果符合ans+=dp[i]*剩余数的全排列
当前集合里有a张A,b张B,那么还能取的牌数:a*-a-b+ #include <bits/stdc++.h>
using namespace std;
#define LL long long
const int inf = 0x3f3f3f3f;
const int MOD =;
const int N =;
#define clc(a,b) memset(a,b,sizeof(a))
const double eps = 1e-;
void fre() {freopen("in.txt","r",stdin);}
void freout() {freopen("out.txt","w",stdout);}
inline int read() {int x=,f=;char ch=getchar();while(ch>''||ch<'') {if(ch=='-') f=-;ch=getchar();}while(ch>=''&&ch<='') {x=x*+ch-'';ch=getchar();}return x*f;}
int n,m,p;
LL dp[<<];
int B[];
LL fac[]={};
int main(){
fac[]=;
for(int i=;i<;i++) fac[i]=fac[i-]*i;
int T,sum,a,b;
scanf("%d",&T);
while(T--){
scanf("%d%d%d",&p,&n,&m);
int N=n+m;
for(int i=;i<<<N;i++) dp[i]=;
for(int i=n;i<N;i++) scanf("%d",&B[i]); dp[]=,sum=,b=,a=;
for(int i=;i<<<N;i++){
if(dp[i]==) continue;
sum=,a=,b=;
for(int j=n;j<N;j++){
if(i&(<<j)){
sum+=B[j];
b++;
}
}
if(sum>=p)continue;
for(int j=;j<n;j++){
if(i&(<<j)){
a++;
}
}
if(a-b+<=) continue;
for(int j=;j<N;j++){
if((i&(<<j))==){
dp[i|(<<j)]+=dp[i];
}
}
}
LL Den=fac[N],Mol=;
for(int i=;i<(<<N);i++){
a=,b=,sum=;
for(int j=n;j<N;j++){
if(i&(<<j)){
b++;sum+=B[j];
}
}
if(sum<p) continue;
for(int j=;j<n;j++){
if(i&(<<j)){
a++;
}
}
Mol+=(LL)dp[i]*fac[N-b-a];
}
LL g=__gcd(Mol,Den);
printf("%I64d/%I64d\n",Mol/g,Den/g);
}
return ;
} 解法2标程:O(^m)
f[i][j]表示A拿i张,B拿j张的方案数
方法用f[i][j]表示A类牌和B类牌分别抽到i张和j张,且抽牌结束前保证i>=j的方案数,这个数组可以用O(n^)的dp预处理得到.
接下来枚举B类牌的每个子集,如果这个子集之和不小于P,用k表示子集的1的个数,将方案总数加上取到这个集合刚好A类卡片比B类卡片少一(过程结束)的方案数:f[k-][k] * C(n, k - ) * (k - )! * k! * (n + m – *k + )! .
如果子集包含了所有的B类卡片,则还需要再加上另一类取牌结束的情况,也就是取完所有牌,此时应加上的方案数为f[n][m] * n! * m! .
最后的总方案数除以(n+m)!就是答案. #include <cstdio>
typedef long long lli; int bc[<<], sum[<<], tmp[<<];
int C[][];
lli f[][], fact[]; lli gcd(lli a, lli b)
{
if (b == ) return a;
return gcd(b, a % b);
} void init()
{
int i, j;
bc[] = ;
for (i=; i<(<<); i++) bc[i] = bc[i^(i&-i)] + ;
fact[] = ;
for (i=; i<=; i++) fact[i] = fact[i-] * i;
C[][] = ;
for (i=; i<=; i++)
{
C[i][] = C[i][i] = ;
for (j=; j<i; j++) C[i][j] = C[i-][j] + C[i-][j-];
}
f[][] = f[][] = ;
for (i=; i<=; i++)
{
f[i][] = ;
for (j=; j<i; j++) f[i][j] = f[i-][j] + f[i][j-];
f[i][i] = f[i][i+] = f[i][i-];
}
} int main()
{
lli a, b, d;
int p, n, m, t, i;
init();
scanf("%d", &t);
while (t --)
{
scanf("%d %d %d", &p, &n, &m);
for (i=; i<m; i++) scanf("%d", &tmp[<<i]);
sum[] = ;
for (i=; i<(<<m); i++) sum[i] = sum[i^(i&-i)] + tmp[i&-i];
a = ;
for (i=; i<(<<m); i++)
{
if (sum[i] >= p && bc[i] <= n + )
{
a += C[n][bc[i]-] * f[bc[i]-][bc[i]] * fact[bc[i]-] * fact[bc[i]] * fact[n+m-*bc[i]+];
if (bc[i] == m && bc[i] < n + ) a += f[n][m] * fact[n] * fact[m];
}
}
b = fact[n+m];
d = gcd(a, b);
printf("%I64d/%I64d\n", a / d, b / d);
}
return ;
}
多校7 HDU5816 Hearthstone 状压DP+全排列的更多相关文章
- hdu-5816 Hearthstone(状压dp+概率期望)
题目链接: Hearthstone Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Other ...
- HDU5816 Hearthstone(状压DP)
题目 Source http://acm.hdu.edu.cn/showproblem.php?pid=5816 Description Hearthstone is an online collec ...
- [多校联考2019(Round 5 T1)] [ATCoder3912]Xor Tree(状压dp)
[多校联考2019(Round 5)] [ATCoder3912]Xor Tree(状压dp) 题面 给出一棵n个点的树,每条边有边权v,每次操作选中两个点,将这两个点之间的路径上的边权全部异或某个值 ...
- 2019牛客多校第五场 F maximum clique 1 状压dp+最大独立集
maximum clique 1 题意 给出一个集合s,求每个子集的最大独立集的权值和(权值是独立集的点个数) 分析 n比较小,一股浓浓的暴力枚举每一个子集的感觉,但是暴力枚举模拟肯定会T,那么想一想 ...
- nefu1109 游戏争霸赛(状压dp)
题目链接:http://acm.nefu.edu.cn/JudgeOnline/problemShow.php?problem_id=1109 //我们校赛的一个题,状压dp,还在的人用1表示,被淘汰 ...
- poj 3254Corn Fields (入门状压dp)
Farmer John has purchased a lush ≤ M ≤ ; ≤ N ≤ ) square parcels. He wants to grow some yummy corn fo ...
- BZOJ 1087: [SCOI2005]互不侵犯King [状压DP]
1087: [SCOI2005]互不侵犯King Time Limit: 10 Sec Memory Limit: 162 MBSubmit: 3336 Solved: 1936[Submit][ ...
- poj3311 TSP经典状压dp(Traveling Saleman Problem)
题目链接:http://poj.org/problem?id=3311 题意:一个人到一些地方送披萨,要求找到一条路径能够遍历每一个城市后返回出发点,并且路径距离最短.最后输出最短距离即可.注意:每一 ...
- [NOIP2016]愤怒的小鸟 D2 T3 状压DP
[NOIP2016]愤怒的小鸟 D2 T3 Description Kiana最近沉迷于一款神奇的游戏无法自拔. 简单来说,这款游戏是在一个平面上进行的. 有一架弹弓位于(0,0)处,每次Kiana可 ...
随机推荐
- C++中全局变量的那些事儿
C/C++中的变量分为全局变量.静态全局变量.局部变量和静态局部变量,在<C/C++中静态局部变量的特点与应用>中我们介绍过静态局部变量,今天我们的目标是全局变量. 单个文件中的全局变量 ...
- iOS Objective-C对象模型及应用
前言 原创文章,转载请注明出自唐巧的技术博客. 本文主要介绍Objective-C对象模型的实现细节,以及Objective-C语言对象模型中对isa swizzling和method swizzli ...
- 关于use-default-filters的一个问题
use-default-filters=true 默认行为会自动扫描所有注解
- java.util.regex.PatternSyntaxException: Unclosed character class near index解决办法
使用str.split("[")时,出现java.util.regex.PatternSyntaxException: Unclosed character class near ...
- [leetcode] Path sum路径之和
要求给定树,与路径和,判断是否存在从跟到叶子之和为给定值的路径.比如下图中,给定路径之和为22,存在路径<5,4,11,2>,因此返回true;否则返回false. 5 / \ 4 8 / ...
- 【翻译】Zakas解答Baranovskiy的JavaScript测验题
原文:http://www.nczonline.net/blog/2010/01/26/answering-baranovskiys-javascript-quiz/ ---------------- ...
- 我的第一个jquery插件:下拉多选框
<!DOCTYPE HTML> <html> <head> <title> New Document </title> <meta n ...
- HDU 4483 Lattice triangle(欧拉函数)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4483 题意:给出一个(n+1)*(n+1)的格子.在这个格子中存在多少个三角形? 思路:反着想,所有情 ...
- TeeChart的X轴,使用伪装的时间
TeeChart曲线的X轴是时间,但是频率很高.没法完全显示. 例如,一秒钟有2000个点,那么点与点的间隔为0.5毫秒. 使用TChart类的GetAxisLabel事件, 函数手册上对此事件的解释 ...
- Windows XP搜索功能 "包含文字" 搜索不到内容的解决办法
Windows开始菜单 -- 运行 -- regedit -- 确定,编辑注册表 HKEY_LOCAL_MACHINE\SYSTEM\ControlSet\Control\ContentIndex 右 ...