这道题关于概率的部分我理解了。
另一点就是转化成01背包的问题。
我是这么想的。
01背包dp时是求在一定容量下的最大价值。
这道题dp时是求获得一定金钱时的最大逃跑概率。
感觉和01背包还是有一点差别。虽然代码写起来很像。
先记录在这里。希望有一天能够彻底的理解这个问题。
附上代码。
#include <stdio.h> #include <string.h> int money[101]; float risk[101]; float dp[10001]; int main() { int T; scanf("%d", &T); int N; float P; int i, j; int sum; while (T--) { scanf("%f %d", &P, &N); P = 1 - P; sum = 0; for (i = 1; i <= N; i++) { scanf("%d %f", &money[i], &risk[i]); sum += money[i]; risk[i] = 1 - risk[i]; } /* 关于概率计算 题目中给出的是偷窃每家银行被抓的概率 要求的是整体被抓的概率 只要偷一家银行时被抓 就是被抓了 有多种情况 都列出来很麻烦 因此可以换一个角度考虑 不被抓只有一种情况,就是偷所有的银行都不被抓 求出这个概率 再用1减去这个概率 就是整体被抓的概率 */ memset(dp, 0, sizeof(dp)); dp[0] = 1; for (i = 1; i <= N; i++) { for (j = sum; j >= money[i]; j--) dp[j] = dp[j] > (dp[j - money[i]] * risk[i]) ? dp[j] : (dp[j - money[i]] * risk[i]); // to help myself understand the question /*for (j = 0; j <= sum; j++) printf("%f ", dp[j]); printf("\n");*/ } for (i = sum; i >= 0; i--) { if (dp[i] >= P) { printf("%d\n", i); break; } } } return 0; }