解题思路:给出一个临界概率,在不超过这个概率的条件下,小偷最多能够偷到多少钱。因为对于每一个银行都只有偷与不偷两种选择,所以是01背包问题。
这里有一个小的转化,即为f[v]代表包内的钱数为v的时候,小偷不被逮捕的概率,这样我们在用
for(i=1;i<=n;i++)
{
for(v=vol;v>=0;v--)
f[v]=max(f[v],f[v-c[i]]*(1-p[i]));
}
的过程中,在求出最大的不被抓的概率过程中,记录下了在此过程中的包中的钱数与此时对应的概率,这样最后只需用一个循环判断在概率大于临界值的时候跳出循环,就得到了偷到的钱数
包的容量是给出的n个银行一共的钱(即为不管给出的那个临界概率是多少,最多能偷到的钱),每一个物品的消耗是该银行存有的钱。每一个物品的价值是(1-p[i])(即在该银行不被抓的概率)
反思:可耻地看了题解,因为老是转化不过去,概率因为是浮点型的不懂怎么转化,然后包的容量是所给出的所有银行所存的钱的和,也没有想到。
Robberies
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 13067 Accepted Submission(s): 4834

His mother, Ola, has decided upon a tolerable probability of getting caught. She feels that he is safe enough if the banks he robs together give a probability less than this.
Notes and Constraints 0 < T <= 100 0.0 <= P <= 1.0 0 < N <= 100 0 < Mj <= 100 0.0 <= Pj <= 1.0 A bank goes bankrupt if it is robbed, and you may assume that all probabilities are independent as the police have very low funds.
#include<stdio.h>
#include<string.h>
int c[105];
double p[105] ,f[10010];
double max(double a,double b)
{
if(a>b)
return a;
else
return b;
}
int main()
{
int ncase,n,i,v,vol;
double m;
scanf("%d",&ncase);
while(ncase--)
{
vol=0;
scanf("%lf %d",&m,&n);
for(i=1;i<=n;i++)
{
scanf("%d %lf",&c[i],&p[i]);
p[i]=1-p[i];
vol+=c[i];
}
memset(f,0,sizeof(f));
f[0]=1;
for(i=1;i<=n;i++)
{
for(v=vol;v>=0;v--)
{
f[v]=max(f[v],f[v-c[i]]*p[i]);
printf("f[%d]=%lf\n",v,f[v]);
}
}
for(i=vol;i>=1;i--)
{
if(f[i]>=1-m)
break;
}
printf("%d\n",i);
}
}