3.小仓的射击练习4
题目描述:
小仓酷爱射击运动。今天的小仓想挑战自我。小仓有N颗子弹,
接下来小仓每次会自由选择K颗子弹进行连续射击,全中靶心的概率为p[k]。
如果成功小仓将获得a[k]的得分,并且可以使用余下子弹继续射击,否则今天的挑战结束。
小仓想知道在最佳策略下,自己能得到的最高期望分数是多少。
输入要求:
第一行一个数N,代表子弹数量。
第二行N个数p[],第 i 个数代表p[i]。
第三行N个数a[],第 i 个数代表a[i]。
1<=N<=5000 0<=p[i]<=1 0<=a[i]<=1000
输出要求:
一个数表示最高期望得分,保留两位小数。
例子:
一
输入:
2
0.80 0.50
1 2
输出:
1.44
解释:
选择用一颗子弹射击:如果命中则再用余下子弹射击(仅剩一颗子弹故只能选择一颗):
0.80 * 1 + 0.80 * 0.80 * 1= 1.44
选择用两颗子弹射击:0.5 * 2 = 1.00
此时最高期望得分为1.44
二
输入:
3
0.90 0.10 0.10
2 1 1
输出:
4.88
解释:
选择用一颗子弹射击:如果命中则再用一颗子弹进行射击,
如果命中则再用一颗子弹进行射击(即3轮均使用了一颗子弹进行):
0.90 * 2 + 0.90 * 0.90 * 2+0.90 * 0.90 * 0.90 * 2= 4.878≈4.88
此种情况的期望得分最高,故为4.88
题解
import java.text.DecimalFormat;
import java.util.Scanner;
/*
小仓酷爱射击运动。今天的小仓想挑战自我。小仓有N颗子弹, 接下来小仓每次会自由选择K颗子弹进行连续射击,全中靶心的概率为p[k]。
如果成功小仓将获得a[k]的得分,并且可以使用余下子弹继续射击,否则今天的挑战结束。 小仓想知道在最佳策略下,自己能得到的最高期望分数是多少。
*/
public class Test3 {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
int n = sc.nextInt();
double[] p = new double[n];
for(int i = 0; i < n; i++){
p[i] = sc.nextDouble();
}
int[] a = new int[n];
for(int i = 0; i < n; i++){
a[i] = sc.nextInt();
}
double[] dp = new double[n+1];
for(int i = 1; i <= n; i++){
for(int j = 1; j <= i; j++){
dp[i] = Math.max(dp[i], p[i-j]*(dp[j-1] + a[i-j]));
}
}
DecimalFormat df = new DecimalFormat("0.00");
System.out.println(df.format(dp[n]));
}
}