Acwing 218. 扑克牌
生活随笔
收集整理的這篇文章主要介紹了
Acwing 218. 扑克牌
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Acwing 218. 撲克牌
題意:
一副撲克牌(54張),問得到A 張黑桃、B 張紅桃、C 張梅花、D 張方塊需要翻開的牌的張數的期望值 E 是多少?
如果翻開的牌是大王或者小王,Admin 將會把它作為某種花色的牌放入對應堆中,使得放入之后 E 的值盡可能小。
題解:
事件發生的期望的線性:
E(aX+bY)=aE(X)+bE(Y)=p(X)×E(X)+p(Y)×E(Y)
我們設dp[a][b][c][d][x][y] = 已經翻開a~d張花色牌,大小王視為x,y花色(若x,y=0則還沒翻開),此時還需要期望翻開多少張牌
dp[u] + = Σp[v] * dp[v],v是u的子狀態
轉移就是枚舉這次翻什么牌,這是以惡搞多終點的dag圖上dp,復雜度為(15 * 4 * 5^2 * 4 )
代碼第33行為什么最后要+1?
我理解的是,這個有點像求圖的路徑期望長度,在本題中,每次操作都是翻一張牌,從u狀態到v狀態是通過翻一張牌,也可以理解成u到所有v的邊權和為1,也就是轉移方程其實應該是:
dp[u] = Σ[dp[v] +1 ] * P[v] =Σdp[v] * P[v] +ΣP[v] =Σdp[v] * P[v]+1
也可以理解,v是u的下一個狀態,那v怎么都要比u多翻一張牌的期望,所有加1
代碼:
#include<bits/stdc++.h> #define MAXN 16 using namespace std; typedef long long ll;const int n = 54; int A,B,C,D;double memo[MAXN][MAXN][MAXN][MAXN][5][5];double dfs(int a, int b, int c, int d, int x, int y){if(memo[a][b][c][d][x][y]) return memo[a][b][c][d][x][y];//到達終狀態 if(a+(x==1)+(y==1)>=A && b+(x==2)+(y==2)>=B && c+(x==3)+(y==3)>=C && d+(x==4)+(y==4)>=D) return 0;double sum = 54-a-b-c-d-(x!=0)-(y!=0);double ans = 0;if(a < 13) ans += (13-a)/sum * dfs(a+1, b, c, d, x, y);if(b < 13) ans += (13-b)/sum * dfs(a, b+1, c, d, x, y);if(c < 13) ans += (13-c)/sum * dfs(a, b, c+1, d, x, y);if(d < 13) ans += (13-d)/sum * dfs(a, b, c, d+1, x, y);if(x==0){double ans1 = 1e18;for(int i=1;i<=4;i++) ans1 = min(ans1, 1/sum * dfs(a, b, c, d, i, y));ans += ans1;}if(y==0){double ans1 = 1e18;for(int i=1;i<=4;i++) ans1 = min(ans1, 1/sum * dfs(a, b, c, d, x, i));ans += ans1;} return memo[a][b][c][d][x][y] = ans + 1; }int main(){cin>>A>>B>>C>>D;int n = max(0, A-13) + max(0, B-13) + max(0, C-13) + max(0, D-13);if(n > 2){cout<<"-1.000"<<endl;return 0;}printf("%.3f\n", dfs(0,0,0,0,0,0));return 0; }總結
以上是生活随笔為你收集整理的Acwing 218. 扑克牌的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 概率与期望
- 下一篇: Keiichi Tsuchiya the