HDU 2955 01背包
题意:一个人去抢银行,给你一个允许的最高被抓概率p,给你n个银行,然后给出n个银行的钱和抢劫该银行的被抓概率,求能获得的最大钱数
思路:开始一直在纠结那个被抓概率的小数问题,发现没办法直接去dp,得转化,可弱鸡我不会阿,看看题解,发现得方向转化一下,对不被抓概率dp
关键一个点我没想到抢多个银行之后不被抓的概率是抢每一个银行不被抓的概率之积,题目给出的是被抓概率,被题目误导了
1 #include<cmath> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 struct Bank 7 { 8 int money; 9 double risk; 10 }bank[10005]; 11 int main() 12 { 13 int t;scanf("%d",&t); 14 while(t--){ 15 int n;double p; 16 scanf("%lf%d",&p,&n); 17 p=1-p; //题目给的是允许被抓的最高概率,现在算的是允许的最低不被抓概率 18 int sum=0; 19 for(int i=0;i<n;++i){ 20 scanf("%d%lf",&bank[i].money,&bank[i].risk); 21 bank[i].risk=1-bank[i].risk;//算出抢劫每一个银行不被抓的概率、 22 sum+=bank[i].money; 23 } 24 double dp[10005]={1.0}; //一分钱也不抢的话不被抓的概率就是百分之百了 25 // dp数组里面存的是dp[i]抢i亿钱最高的不被抓概率 26 // 你想要不被抓,那么不被抓的概率一定要越高越好 27 for(int i=0;i<n;++i) 28 for(int j=sum;j>=bank[i].money;--j) 29 dp[j]=max(dp[j],dp[j-bank[i].money]*bank[i].risk); //而抢多个银行之后不被抓的概率是抢每一个银行不被抓的概率之积 30 for(int i=sum;i>=0;--i) //想想:抢钱越多的话不被抓概率一定越低 31 if(dp[i]-p>1e-9){ //找寻第一个不被抓概率大于等于p的 32 printf("%d\n",i); 33 break; 34 } 35 } 36 return 0; 37 }