现在的位置: 首页 > 综合 > 正文

背包入门 01背包 hdu 2955 Robberies

2019年09月02日 ⁄ 综合 ⁄ 共 812字 ⁄ 字号 评论关闭

不是一个背包问题。但是,问题经变化后与01背包思路上别无二致。

注意到不被逮捕的条件:1-(1-p1)(1-p2)(1-p3)...(1-pk)<p(其中p表示最大危险概率),不妨将问题转化,使dp[i][j]表示对于前i个银行,可取总金额为j时,最大的安全的概率;

那么dp[i][j]=max(dp[i-1][j],dp[i-1][j-m[i]]*p[i])(其中p[i]表示抢劫第i个银行的最大安全概率)

运用01 背包解出dp[i](运用了压缩空间的技巧,使二维变一维)后,注意到,随着i(表示可取金额)增大,dp[i]不减,那么显然,安全情况中最危险的情况对应的金额便是问题的最后答案。

这里给出一维写法:

#include<stdio.h>
#include<algorithm>
#include<string.h>
using namespace std;
double p[10005],dp[10005];
int m[105];
int vol;//all the money
int main()
{
   int t;
   scanf("%d",&t);
   while(t--)
   {
      memset(dp,0,sizeof(dp));
      int n;
      double maxp;
      scanf("%lf%d",&maxp,&n);
      maxp=1-maxp;
      vol=0;
      for(int i=1;i<=n;i++)
      {
         scanf("%d%lf",&m[i],&p[i]);
         p[i]=1-p[i];
         vol+=m[i];
      }
      dp[0]=1;//improtant 
      for(int i=1;i<=n;i++)
      {
         for(int v=vol;v>=m[i];v--)
         {
            dp[v]=max(dp[v],dp[v-m[i]]*p[i]);
         }
      }
      for(int maxm=vol;maxm>=0;maxm--)
         if(dp[maxm]>=maxp)
         {
            printf("%d\n",maxm);
            break;
         }
   }
   return 0;
}

抱歉!评论已关闭.