36張牌分成9堆,每堆4張牌。每次可以拿走某兩堆頂部的牌,但需要點數相同。如果有 多種拿法則等概率的隨機拿。例如,9堆頂部的牌分別為ks, kh, kd, 9h, 8s, 8d, 7c, 7d, 6h,則有5種拿法(ks,kh), (ks,kd), (kh,kd), (8s,8d), (7c,7d),每種拿法的概率均為1/5。 如果最後拿完所有牌則遊戲成功。按順序給出每堆牌的4張牌,求成功概率。
為啥一張牌是兩個字元組成??這什麼奇怪的牌??按照題面給的例子就是說,只要第乙個字元相同就ok了吧。。
於是我們考慮預處理存每一堆牌的每一位的花色的狀態,然後因為牌的數量很少,開個九維的dp來存狀態,用記憶化搜尋轉移。
其實轉移方法就很簡單了,在dfs裡列舉相同的兩堆堆頂,然後把這兩堆頂部的牌取走作為下乙個狀態,計算一共有多少方案數以及這些方案數成功的概率之和。
那麼本狀態成功的概率就是 ∑可達的下乙個狀態成功概率 ÷ 可達的方案數
而邊界就是全部取光的狀態的成功概率為100%
#includeusingnamespace
std;
#define n 6
int a[15][15
];
char s[15][15
];
intvis[n][n][n][n][n][n][n][n][n];
double
dp[n][n][n][n][n][n][n][n][n];
inline
void
init()
inline
double dfs(int p1,int p2,int p3,int p4,int p5,int p6,int p7,int p8,int
p9)
;
for(int i=1;i<=9;i++)
if(tmp[i])
if(ok)return dp[p1][p2][p3][p4][p5][p6][p7][p8][p9]=1.0
;
double possibility=0.0
;
for(int i=1;i<=9;i++)
for(int j=i+1;j<=9;j++)
if(tmp[j]&&tmp[i]&&a[i][tmp[i]]==a[j][tmp[j]])
if(tot)dp[p1][p2][p3][p4][p5][p6][p7][p8][p9]=possibility/(1.0*tot);
return
dp[p1][p2][p3][p4][p5][p6][p7][p8][p9];
}
intmain()
dfs(
4,4,4,4,4,4,4,4,4
);
printf(
"%.6lf\n
",dp[4][4][4][4][4][4][4][4][4
]);
} }
UVa1637 紙牌遊戲
uva1637 紙牌遊戲 36 張牌分成 9 堆,每堆 4 張牌。每次可以拿走某兩堆頂部的牌,但需要點數相同。如果有多種拿法則等概率的隨機拿。例如,9 堆頂部的牌分別為 ks,kh,kd,9h,8s,8d,7c,7d,6h 則有 5 種拿法 ks,kh ks,kd kh,kd 8s,8d 7c,7d...
例題 10 12 紙牌遊戲 UVa 1637
題意 36張牌分成9堆,沒堆4張,每次可以拿走某兩堆頂部的牌,但需要的點數相同,如果有多種拿法就等概率隨機拿,問拿完所有牌的概率。分析 直接用9元組表示當前狀態,即每堆剩餘的牌數,狀態數為5 9 1953125。設d i 表示狀態i對應的概率,則根據全概率公式,d i 為後繼狀態的成功概率的平均值,...
UVa 1637 紙牌遊戲(全概率公式)
題意 36張牌分成9堆,每堆4張牌。每次可以拿走某兩堆頂部的牌,但需要點數相同。每種拿法的概率均為1 5。求成功概率。思路 可以用9元組來表示當前狀態,d i 表示狀態i對應的成功概率。根據全概率公式 乙個狀態的成功率,等於其後繼狀態的成功率的平均值。看到別人用vector來簡潔的表示了狀態,值得學...