Toss Strange Coins

medium dynamic programming probability math

Problem

You have a list of biased coins, where prob[i] is the probability that the i-th coin lands heads when tossed. Toss every coin exactly once and return the probability that the number of coins showing heads equals target.

Inputprob = [0.5, 0.5, 0.5], target = 2
Output0.375
There are C(3, 2) = 3 ways to pick which two coins are heads, each with probability 0.5³ = 0.125, so 3 × 0.125 = 0.375.

def toss_strange_coins(prob, target):
    dp = [0.0] * (target + 1)
    dp[0] = 1.0
    for p in prob:
        for j in range(target, -1, -1):
            dp[j] = dp[j] * (1 - p) + (dp[j - 1] * p if j > 0 else 0.0)
    return dp[target]
function tossStrangeCoins(prob, target) {
  const dp = new Array(target + 1).fill(0);
  dp[0] = 1;
  for (const p of prob) {
    for (let j = target; j >= 0; j--) {
      dp[j] = dp[j] * (1 - p) + (j > 0 ? dp[j - 1] * p : 0);
    }
  }
  return dp[target];
}
class Solution {
    public double tossStrangeCoins(double[] prob, int target) {
        double[] dp = new double[target + 1];
        dp[0] = 1.0;
        for (double p : prob) {
            for (int j = target; j >= 0; j--) {
                dp[j] = dp[j] * (1 - p) + (j > 0 ? dp[j - 1] * p : 0.0);
            }
        }
        return dp[target];
    }
}
double tossStrangeCoins(vector<double>& prob, int target) {
    vector<double> dp(target + 1, 0.0);
    dp[0] = 1.0;
    for (double p : prob) {
        for (int j = target; j >= 0; j--) {
            dp[j] = dp[j] * (1 - p) + (j > 0 ? dp[j - 1] * p : 0.0);
        }
    }
    return dp[target];
}
Time: O(n · target) Space: O(target)