lightoj 1079 Just another Robbery 概率 背包
题目中给的都是被逮捕的概率p,并不方便计算,所以统统通过1-p,变成q,表示安全的概率。
然后这么多银行可以选择,有些类似背包问题。开始下意识认为应该是安全概率算体积,金钱算价值,更符合直观想法。但安全概率不是整数,这样子没法dp。
但是背包有个技巧,有时候体积可能是直观上的价值,我们不妨把金钱作为体积试试。
dp[i][j]表示,考虑前i个银行,拿了j的金钱,的最大安全概率。
dp[i][j] = max(dp[i - 1][j],dp[i - 1][j - v[i]] * q[i]),我们再滚动数组一下就好了。倒叙遍历dp[i],输出第一个大于1-P即可。
1 #include <cstdio> 2 #include <cmath> 3 #include <algorithm> 4 #include <cstring> 5 using namespace std; 6 int n,T,cas; 7 int v[105]; 8 double P; 9 double p[105],q[105],dp[10005]; 10 int main() 11 { 12 for (scanf("%d",&T);T != 0;T--) 13 { 14 cas++; 15 memset(dp,0,sizeof(dp)); 16 scanf("%lf%d",&P,&n); 17 for (int i = 1;i <= n;i++) 18 { 19 scanf("%d%lf",&v[i],&p[i]); 20 q[i] = 1 - p[i]; 21 } 22 dp[0] = 1; 23 for (int i = 1;i <= n;i++) 24 for (int j = 10000;j >= 0;j--) 25 if (j >= v[i]) 26 dp[j] = max(dp[j],dp[j - v[i]] * q[i]); 27 for (int i = 10000;i >= 0;i--) 28 if (dp[i] >= 1 - P) 29 { 30 printf("Case %d: %d\n",cas,i); 31 break; 32 } 33 } 34 return 0; 35 }
心之所动 且就随缘去吧