hdu 2955 01背包

Posted 三人行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 2955 01背包相关的知识,希望对你有一定的参考价值。

      题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2955

    这题蛮有意思的,首先01背包的状态转移这些不说了,很简单。但关键这题该如何建立起01背包的模型那?如果以被抓的概率作为背包容量,由于浮点数,精度是不可靠的。

所以只能以金钱为背包容量,所以所有银行的总资产,最为背包容量,然后我们以逃跑几率进行动态转移。逃跑几率只要 用 1- p 就好了,关键一点由于是算的概率,所以逃跑

几率是想乘的,大家可以想想,不可能相加。最后我们就能完美写成代码了。(还有如果没抢到,那么概率为1 ,这也不要忽略了)

 

AC code:

#include <bits/stdc++.h>
using namespace std;
const int MAX = 10006;

/*hdu2955 01背包--这里我们考虑以金钱为容量*/

 
 int main ()
{
  int T,n,t[101];
  float p,v[101];
  float f[MAX];
  cin>>T;
  while(T--)
  {
      cin >> p >> n;
      p = 1-p;//最低逃生几率 
      memset (f,0,sizeof(f));
      int sum = 0;
    for (int i=0;i<n;++i)
    {
          cin>>t[i]>>v[i];
          v[i] = 1-v[i];//这样就变成了逃生几率,逃生几率越大越好 
          sum +=t[i];
      }
   f[0] = 1;//没抢到钱,逃走概率100% 
   for (int i=0;i<n;++i)
      for (int j= sum;j>=t[i];--j )
       {
        f[j] = max (f[j],f[j-t[i]]*v[i]);//这里一定要乘,因为你这是算概率,在前面逃走的概率下。 
     }
     int fg = 0;
    for (int i=sum;i>=0;--i)
     if (f[i] >= p) {
         fg = i;break;
     } 
    cout<<fg<<endl;
  } 
  
return 0;
}
/*
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
*/

 

以上是关于hdu 2955 01背包的主要内容,如果未能解决你的问题,请参考以下文章

HDU2955(01背包)

hdu2955 Robberies (01背包)

01背包+卡精度 Hdu 2955

HDU 2955 01背包 / 小数

HDU 2955 01背包+小数概率

hdu-2955(01背包+逆向思维+审题)