标签:
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955
题意:Roy想要抢劫银行,每家银行多有一定的金额和被抓到的概率,知道Roy被抓的最大概率P,求Roy在不被抓的情况下,抢劫最多。
分析:
当前的概率基于前一种状态的概率,即偷n家银行而不被抓的概率等于偷n-1家银行不被转的概率乘以偷第n家银行不被抓的概率。
用dp[i]表示偷价值为 i 时不被抓的概率,则状态转移方程为:
dp[j] = max(dp[j] , dp[j-m[i]] * (1-p[i]));
原意是提供银行个数和期望被捕概率,然后将每个银行的钱数和逃脱概率给出,通过将总数当作背包大小,通过求最大逃脱概率当作最大价值(但是并不是求这个),最终通过从总钱数递减找到低于期望被捕概率第一项背包, 即为不被逮捕的所能强盗的最大钱数。
Sample Input 3 0.04 3 1 0.02 2 0.03 3 0.05 0.06 3 2 0.03 2 0.03 3 0.05 0.10 3 1 0.03 2 0.02 3 0.05 Sample Output 2 4 6
************************************************
1 #include<iostream> 2 #include<algorithm> 3 #include<cstdio> 4 #include<cstring> 5 #include<queue> 6 #include<stdlib.h> 7 #include<map> 8 #include<cmath> 9 10 using namespace std; 11 12 #define N 25000 13 #define INF 0x3f3f3f3f 14 15 double dp[N]; 16 17 int main() 18 { 19 int T,n,m[N],i,j,sum; 20 double p,g[250]; 21 22 scanf("%d", &T); 23 24 while(T--) 25 { 26 scanf("%lf %d", &p,&n); 27 28 sum=0; 29 p=1-p;///安全逃脱的概率 30 31 for(i=0;i<n;i++) 32 { 33 scanf("%d %lf",&m[i], &g[i]); 34 sum+=m[i];///抢劫所有的银行的金额 35 g[i]=1-g[i];///抢劫每家银行的逃脱概率 36 } 37 38 memset(dp,0,sizeof(dp)); 39 dp[0]=1; 40 41 for(i=0;i<n;i++) 42 for(j=sum;j>=m[i];j--) 43 if(dp[j]<dp[j-m[i]]*g[i]) 44 dp[j]=dp[j-m[i]]*g[i];///小偷偷j钱逃脱的最大概率 45 46 for(i=sum;i>=0;i--) 47 if(dp[i]>=p) 48 { 49 printf("%d\n", i); 50 break; 51 } 52 53 /*for(i=sum;i>=0&&dp[i]<p;i--); 54 printf("%d\n", i);/*/ 55 56 } 57 return 0; 58 }
/假设你有一个数组int a[5];那么你可以这样给数组赋值
for(int i = 0;i<5;i++)
a[i]=i;
这个是没加分号的,那么a[0]=0,a[1]=1....a[4]=4;
for(int i = 0;i<5;i++);这样加了分号,就代表结束了,相当于循环只执行了i,然后就退出循环了
a[i]=i;//这样相当于只有a[4]=4;
标签:
原文地址:http://www.cnblogs.com/weiyuan/p/5750500.html