LintCode刷题—— 背包问题 IX(动态规划)
问题描述
你总共有n
万元,希望申请国外的大学,要申请的话需要交一定的申请费用,给出每个大学的申请费用以及你得到这个大学offer的成功概率,大学的数量是 m
。如果经济条件允许,你可以申请多所大学。找到获得至少一份工作的最高可能性。
0<=n<=10000,0<=m<=10000
样例
样例 1:
输入:
n = 10
prices = [4,4,5]
probability = [0.1,0.2,0.3]
输出: 0.440
解释:
选择第2和第3个学校。
样例 2:
输入:
n = 10
prices = [4,5,6]
probability = [0.1,0.2,0.3]
输出: 0.370
解释:
选择第1和第3个学校。
AC代码
1 public class Solution { 2 /** 3 * @param n: Your money 4 * @param prices: Cost of each university application 5 * @param probability: Probability of getting the University's offer 6 * @return: the highest probability 7 */ 8 public double backpackIX(int n, int[] prices, double[] probability) { 9 // write your code here 10 int m = prices.length; 11 if (n == 0) { 12 return 0; 13 } 14 15 // 还是0-1背包问题 dp[i][j] 前i所学校总共j万元,获得至少一份工作的最高可能性 16 // 就是将所有的可能情况的概率都加起来就是最高可能性 17 // 滚动数组 18 double[][] dp = new double[2][n + 1]; 19 20 dp[0][0] = 0; 21 22 for (int i = 1; i <= 1; i++) { 23 dp[i][0] = 0; 24 } 25 26 for (int i = 1; i <= n; i++) { 27 dp[0][i] = 0; 28 } 29 30 int old = 0; 31 int now = 1; 32 // 这里先考虑的是学校,再考虑的是费用 33 for (int i = 1; i <= m; i++) { 34 old = now; 35 now = 1 - now; 36 for (int j = 1; j <= n; j++) { 37 if (prices[i - 1] > j) { 38 dp[now][j] = dp[old][j]; 39 } else { 40 // 选或不选比大小 41 double a = dp[old][j - prices[i - 1]] * probability[i - 1]; 42 double b = (1 - dp[old][j - prices[i - 1]]) * probability[i - 1]; 43 double c = dp[old][j - prices[i - 1]] * (1 - probability[i - 1]); 44 dp[now][j] = Math.max(dp[old][j], a + b + c); 45 } 46 } 47 } 48 49 return dp[now][n]; 50 } 51 }