一开始觉得是计算出一个数学公式。。但肯定不可能
那方法肯定是 dp 了。
DP
dp 数组是一个二维数组,两个坐标分别代表次数和当前是第几个硬币。这一点先想想用递归怎么做,再寻找递归中的关键参数,转化成 dp 的坐标即可。
最后要的到结果是 dp[target][N-1]。
已知项为 dp 第 0 列的所有项。即
double[][] dp = new double[target+1][N];
dp[0][0]=1-prob[0];
dp[1][0]=prob[0];
然后递归关系也比较好找,自己画个图就知道 dp[i][j] 可由 dp[i][j-1] 和 dp[i-1][j-1] 转化而来。
所以最后的代码如下:
class Solution {
public double probabilityOfHeads(double[] prob, int target) {
if(target==0){
double res = 1;
for(int i=0;i<prob.length;i++){
res *= (1 - prob[i]);
}
return res;
}
int N = prob.length;
double[][] dp = new double[target+1][N];
dp[0][0]=1-prob[0];
dp[1][0]=prob[0];
for(int j=1;j<N;j++){
for(int i=0;i<=target;i++){
dp[i][j]+=dp[i][j-1]*(1-prob[j]);
if(i>0) {
dp[i][j] += dp[i - 1][j - 1] * prob[j];
}
}
}
return dp[target][N-1];
}
public static void main(String[] args) {
double[] a = {0.5,0.5,0.5,0.5,0.5};
int b=1;
System.out.println(new Solution().probabilityOfHeads(a,b));
}
}
总结
这道题是一道典型的 dp 题,只需要按照一般 dp 的思路就行。
- 分析 dp 数组的坐标变量和范围。
- 分析最后返回的值在哪。
- 已知哪些值。
- 递推关系是什么?