1. 程式人生 > >hdu5816 多校7 Hearthstone【組合計數+dp】

hdu5816 多校7 Hearthstone【組合計數+dp】

題目大意:
牌堆有n張奧術牌,奧術牌可以再從牌堆摸兩張牌, m張傷害牌,傷害各為xi,初始從牌堆摸一張,問本回合能擊殺給定hp的對手的概率,結果用分數表示。(n+m<=20)

如果n < m, 回合中能抽取的牌數為k-1張奧術牌, k張傷害牌,
列舉所有的傷害牌組合,如果 k張傷害和>= hp且k-1<=n,說明這種牌組能被抽到並且能擊殺對手,計算出這種傷害組合的所有牌序組合數 dp[k1][k]Ck1nk1!k(n+m2k+1)!,累加即可;
其中dp[i][j] 為將奧術牌看做一種,傷害牌看做一種下,i 張奧術和 j 張傷害的組合數,可以看出i>=j-1,

初始dp[0][0] = 0, dp[0][1] = 1;
遞推關係為dp[i][0] = 1, dp[i][j] = dp[i-1][j] + dp[i][j-1] (j < i), dp[i][j] = dp[i][[j-1] (i<=j<=i+1);
(感覺不怎麼好想,渣渣打表找的規律。。)

如果n >= m並且xi>=hp,多了一種特殊情況,牌堆的牌數不夠抽,只能n張奧術,m張傷害(而不是n+1),加上dp[n][m] * n! * m!;

最後答案除以總牌序(m+n)!
複雜度O(2m)

#include <cstdio>
#include <cstring>
#include <algorithm> using namespace std; typedef long long LL; int hp, n, m; int x[25]; LL c[25][25], a[25], dp[25][25]; //c: 組合數 a: 階乘 dp:i奧術j傷害組合數 LL ans; void init() //預處理 { c[0][0] = 1; for(int i = 1; i <= 20; i++) { c[i][0] = 1; for(int j = 1;j <= i; j++) c[i][j] = c[i-1
][j-1] + c[i-1][j]; } a[0] = 1; for(int i = 1; i <= 20; i++) a[i] = a[i-1] * i; memset(dp, 0, sizeof(dp)); dp[0][0] = 0; dp[0][1] = 1; for(int i = 1; i <= 20; i++) { dp[i][0] = 1; for(int j = 1; j < i; j++) dp[i][j] = dp[i-1][j] + dp[i][j-1]; dp[i][i] = dp[i][i+1] = dp[i][i-1]; } } void dfs(int cur, int s, int k) { if(k > n+1) return; for(int i = cur; i < m; i++) { if(s+x[i] >= hp) { if(k == 1) ans += a[n+m-1]; else ans += dp[k-1][k] * c[n][k-1] * a[k-1] * a[k] * a[n+m-2*k+1]; if(k == m && n >= m) ans += dp[n][m] * a[n] * a[m]; } dfs(i+1, s+x[i], k+1); } } int main(int argc, char const *argv[]) { init(); int t; scanf("%d", &t); while(t--) { scanf("%d%d%d", &hp, &n, &m); for(int i = 0; i < m; i++) scanf("%d", &x[i]); ans = 0; dfs(0, 0, 1); LL all = a[n+m]; LL g = __gcd(ans, all); if(ans) printf("%I64d/%I64d\n", ans/g, all/g); else printf("0/1\n"); } return 0; }

相關推薦

hdu5816 7 Hearthstone組合計數+dp

題目大意: 牌堆有n張奧術牌,奧術牌可以再從牌堆摸兩張牌, m張傷害牌,傷害各為xi,初始從牌堆摸一張,問本回合能擊殺給定hp的對手的概率,結果用分數表示。(n+m<=20) 如果n

P1282 米諾骨牌 01揹包DP

多米諾骨牌有上下2個方塊組成,每個方塊中有1~6個點。現有排成行的 上方塊中點數之和記為S1,下方塊中點數之和記為S2,它們的差為|S1-S2|。例如在圖8-1中,S1=6+1+1+1=9,S2=1+5+3+2=11,|S1-S2|=2。每個多米諾骨牌可以旋轉180°,使得

組合數學dpEducational Codeforces Round 51 (Rated for Div. 2) D. Bicolorings

Step1 Problem: 給你 2*n 的矩陣,你可以對於每個格子填塗黒色或者白色,如果相鄰顏色一樣看成同一塊,問你塗完後恰好有 k 塊的方案數。 資料範圍: 1 <= n <= 1000, 1 <= k <= 2n. Step2

組合數學dpACM-ICPC 2018 徐州賽區網路預賽 A. Hard to prepare

Step1 Problem: 給你 n 個數排成一圈,每個數的範圍[0, 2^k-1],相鄰兩個數字它們異或值不能為 2^(k-1),求滿足條件的排列數。 資料範圍: T<=20, 0 < n, k<=1e6. Step2 Ideas:

組合計數UVA - 11538 - Chess Queen

bre cpp name using blog ios log return algorithm 考慮把皇後放在同一橫排或者統一縱列,答案為nm(m-1)和nm(n-1),顯然。 考慮同一對角線的情況不妨設,n<=m,對角線從左到右依次為1,2,3,...,n-1,n

Hotaru&#39;s problem(hdu5371+Manacher)7

uri ems sample onos none mes ted pro ron Hotaru‘s problem Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav

HDU 6124 177 Euler theorem(簡單思維題)

panel please problem urn return bottom -1 fan std Problem Description HazelFan is given two positive integers a,b, and he wants to calcu

牛客7

ase ace rst gcc 技術分享 prot 好的 bre size A 隊友寫的。 //#pragma comment(linker, "/stack:200000000") //#pragma GCC optimize("Ofast,no-stack

HDU-63957 Sequence(除法分塊+矩陣快速冪)

review lse %d sca code left define hdu fin Sequence Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 262144/262144 K (Java/Others

概率與期望組合計數TopCoder SRM 561 Orienteering

題意: 給出一顆樹,樹上有些選中點 C C C,現在隨機從中選擇一個大小為

HDU6331&&183M Walking Plan 分塊+DP

Time Limit: 5000/2500 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) Total Submission(s): 633    Accepted Submissi

HDU 6327&&18訓練3I DP

Problem I. Random Sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 524288/524288 K (Java/Others) Total Submissio

2016訓練#1 1002 組合博弈

              對於一開始接觸博弈論的同學來說,這道題的思路略難,但是如果想到了把1*20的棋盤想象成一個20位的二進位制數,然後通過sg函式預處理得到每一個二進位制數相應的sg'值,最後直接用每一行的sg值相亦或即可。注意mex陣列,也就是vis陣列可以開得大

組合+錯排BZOJ4517(Sdoi2016)[排列計數]題解

題目概述 如果 ai=i 則 i 是穩定的。給出 n,m ,求穩定數為 m 的 n 的排列的個數。 解題報告 其實很簡單……先選出 m 個穩定位置,然後另外 n−m 強制不穩定。 強制不穩定

2017HDU7

題目連結 一些題解 05 Euler theorem  本場的水題,給定一個a問任意的b讓a % b有幾種可能的值。  可以得見0 - (a / 2 - 1)都是可以得到的值, 而且其本身也是可以得到的值所以得到程式碼。 #in

北京pk10公式大全論壇更高手交流群vX:zhi845545

計算機兩三把不中,輸了設定的金額,那麽鎖定單獨號碼的時候,9,就打死不下了,所以這就是讓玩家們更好去利用的一個非常重要的因素,7,這是保證人們能夠更好去利用的一個非常重要的因素,4,也馬上收了,? 六:投3,贏錢的人都是頭腦清晰,每天贏一定的錢了,還[b]北京pk10公式大全論壇[/b]是能夠很好的去利用並且

[ZJOI2010]排列計數 (組合計數/dp)

數據 限制 getchar() 計算 由於 文件中 pre 模擬 inline [ZJOI2010]排列計數 題目描述 稱一個1,2,...,N的排列P1,P2...,Pn是Magic的,當且僅當2<=i<=N時,Pi>Pi/2. 計算1,2,...N的

LibreOJ10077. 「一本通 3.2 練習 3」最短路計數最短路+DP

10077. 「一本通 3.2 練習 3」最短路計數 【題目描述】 傳送門 【題解】 這題我們知道如何判斷這條邊是不是最短路上的邊,那麼就可以DP求解了。但是要注意順序,我們可以預處理出最短路路徑(x,y),然後BFS走DP就可以了。 程式碼如下 #includ

slim|lumen|laravel 組合查詢 union

一。基礎概念解釋 定義: 在大多數開發中,使用一條SELECT查詢就會返回一個結果集。如果,我們想一次性查詢多條SQL語句,並將每一條SELECT查詢的結果合併成一個結果集返回。就需要用到Union操作符,將多個SELECT語句組合起來,這種查詢被稱為並(Uni

組合數學 && dp[i][j] = a*dp[i, j-1] + b*dp[i-1,j]+c 求 dp[n][n]Gym

Step1 Problem: 已知 a,b,ca, b, ca,b,c 和 dp[k][1],dp[1][k]dp[k][1], dp[1][k]dp[k][1],dp[1][k] 其中 k=1,2,3,...,n.k = 1, 2, 3, ..., n.k=