一個袋子裏有W個白豆子,R個紅豆子。第一步: 隨機摸一個豆子,摸到白豆子直接吃,摸到紅豆子,放回去。第二步:隨機再摸一豆子,無論是紅是白,都吃。而後重複第一步和第二步,問最後一個豆子是白豆子的機率。面試
考慮dp[i][j]表示剩下i個白豆子,j個紅豆子的機率,則根據題意有兩種轉移。算法
dp[i][j]表示當前剩下i顆白豆子j顆紅豆子的機率,dp[w][r] =1,因爲第二步一定會吃一顆豆子,因此執行(w + r) * 2步必定能夠把全部的豆子吃完,考慮再加一維,dp[i][j][k]表示當前執行到第i步,剩下j顆白豆子k顆紅豆子的機率,而後對應對於每一步就能夠轉移了。bash
www.jiuzhang.com/solution/ea…網站
/**
* 本參考程序來自九章算法,由 @斌助教 提供。版權全部,轉發請註明出處。
* - 九章算法致力於幫助更多中國人找到好的工做,教師團隊均來自硅谷和國內的一線大公司在職工程師。
* - 現有的面試培訓課程包括:九章算法班,系統設計班,算法強化班,Java入門與基礎算法班,Android 項目實戰班,
* - Big Data 項目實戰班,算法面試高頻題班, 動態規劃專題班
* - 更多詳情請見官方網站:http://www.jiuzhang.com/?source=code
*/
public class Solution {
/**
* @param w: The W
* @param r: The R
* @return: The answer
*/
public double eatTheBeans(int w, int r) {
// Write your code here
double[][][] dp = new double[281][71][71];
int n = (w + r) * 2;
for(int i = 0; i <= n; i++) {
dp[i] = new double[71][71];
for(int j = 0; j <= w; j++) {
dp[i][j] = new double[71];
for(int k = 0; k <= r; k++) {
dp[i][j][k] = 0;
}
}
}
dp[0][w][r] = 1;
if(w == 1 && r == 0) {
return dp[0][w][r];
}
for(int i = 1; i <= n; i++) {
for(int j = w; j >= 0; j--) {
for(int k = r; k >= 0; k--) {
if(j + k == 0) {
continue;
}
if(dp[i - 1][j][k] != 0) {
if(i % 2 == 1) {
if(j - 1 >= 0) {
dp[i][j - 1][k] += 1.0 * j / (j + k) * dp[i - 1][j][k];
}
dp[i][j][k] += 1.0 * k / (j + k) * dp[i - 1][j][k];
} else {
if(j - 1 >= 0) {
dp[i][j - 1][k] += 1.0 * j / (j + k) * dp[i - 1][j][k];
}
if(k - 1 >= 0) {
dp[i][j][k - 1] += 1.0 * k / (j + k) * dp[i - 1][j][k];
}
}
}
}
}
}
double ans = 0;
for(int i = 1; i <= n; i++) {
ans += dp[i][1][0];
}
return ans;
}
}複製代碼