题目描述:小明同学要参加一场考试,考试一共有n道题目,小明必须做对至少60%的题目才能通过考试。考试结束后,小明估算出每题做对的概率,p1,p2,...,pn。你能帮他算出他通过考试的概率吗?
输入:第一行一个数n(1<=n<=100),表示题目的个数。
第二行n个整数,p1,p2,...,pn。表示小明有pi%的概率做对第i题。(0<=pi<=100)
样例输入:
4
50 50 50 50
输出:小明通过考试的概率,最后结果四舍五入,保留小数点后五位。
样例输出:0.3125
解题思路:这道题目是典型的动态规划题目。用空间换取时间。
1、给出n道题目,要想通过这次考试,必须答对题目的最少个数为m=0.6*n上取整;
2、初始化:0道题目,做对0道题目的概率为1;0道题目做对题目的个数j>0时,概率为0;
3、针对i道题目,做对j道题目的概率为两种情况:
3.1前i-1道题目,做对j道题目,则第i道题目做错,概率为:p[i-1][j]*(1-p[i-1])
3.2前i-1道题目,做对j-1道题目,则第i道题目做对,概率为p[i-1][j-1]*p[i-1]
总上:p[i][j]=p[i-1][j]*(1-p[i-1])+p[i-1][j-1]*p[i-1]
4、变量二维数组,将满足条件(答对题目的个数>=m)的数相加,输出最后的概率即可。
public class Q2017_通过考试_DP方法 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
double[] pros = new double[n];
for(int i=0; i<n; i++){
int everyQuestion = sc.nextInt();
pros[i] = (double)everyQuestion/100;
}
double[][] pass = new double[n+1][n+1];
pass[0][0] = 1;//初试条件
for(int i=1; i<=n; i++){
//初试化第一列,所有情况下答对0道题目的概率
pass[i][0] = pass[i-1][0]*(1-pros[i-1]);
for(int j=1; j<=n; j++){//求解第i题得答题情况
pass[i][j] = pass[i-1][j-1]*pros[i-1] + pass[i-1][j]*(1-pros[i-1]);
}
}
double passPro=0.0d;
for(int i=(3*n+4)/5; i<=n; i++){
passPro += pass[n][i];//最后一行,大于要答对题目的概率的总和
}
System.out.println(String.format("%.5f", passPro));//注意输出格式,小数点后5位
}
}