代码改变世界

HDU--2955 Robberies( 01背包)

2013-12-06 19:13  gongti  阅读(260)  评论(0)    收藏  举报
题目http://acm.hdu.edu.cn/showproblem.php?pid=2955

分析:这个题目和此题有着类似的地方,就是不能直接将“效益”(NYOJ860指价值,HDU2955指风险)
的值作为dp[]数组的大小。原因是前一个数据太大了,后一个则是浮点数。因此都要将背包问题中“价值”和“重量”互换。
同时只有每一个银行都不被抓,才会不被抓。这里使用乘法原则。
#include<stdio.h>
#include<string.h>

const int INF=1<<30;

int main()
{
  int T,N,m[102],sum;
  float P,p[102],dp[10010];
  scanf("%d",&T);
  while (T--)
  {
    scanf("%f%d",&P,&N);
    sum=0;
    for(int i=1;i<=N;i++)
      {
        scanf("%d%f",&m[i],&p[i]);
        sum+=m[i];
      }

    for(int i=0;i<=sum;i++) dp[i]=0;  //也可以dp[i]=-INF
    dp[0]=1;//很关键,在抢劫为0时不被抓概率为1

    for(int i=1;i<=N;i++)
      for(int j=sum;j>=m[i];j--)
        dp[j]=dp[j]>dp[j-m[i]]*(1-p[i])?dp[j]:dp[j-m[i]]*(1-p[i]);

   for(int i=sum;i>=0;i--)
    if(1-dp[i]<=P)
      {
        printf("%d\n",i);
        break;
      }
  }
  return 0;
}