HDU 2955 Robberies 01背包

题目大意:有个小偷要求抢银行(坏蛋),现在给出你一个安全的值p(即危险系数不高于P则认为是安全的),和银行数目N。下面N行每行两个数字:抢劫该银行能获得的钱数和抢劫该银行的危险系数。 求在不高于P的情况下最多能抢多少钱(坏人)。

 

题目大意:基本上是01背包的模板了,和之前一道 I NEED A OFFER 一样,需要预处理一下、预处理方法也已样就不多说了,有疑问的可以看我 I NEED A OFFER 的题解~

 

#include<cstdio>
#include<stdio.h>
#include<cstdlib>
#include<cmath>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>
#include<queue>
#define INF 0x3f3f3f3f
#define MAX 1000005
#define mod 1000000007

using namespace std;

double dp[MAX],w[MAX];
int v[MAX];

int main()
{
    int n,i,j,T,sum;
    double p;

    scanf("%d",&T);

    while(T--)
    {
        memset(dp,0,sizeof(dp));
        scanf("%lf%d",&p,&n);
        sum=0;
        for(i=1;i<=n;i++)
        {
            scanf("%d%lf",&v[i],&w[i]);
            sum+=v[i];
            w[i]=1-w[i];//预处理一下
        }

        dp[0]=1;

        for(i=1;i<=n;i++)
        {
            for(j=sum;j>=v[i];j--)
            {
                dp[j]=max(dp[j],dp[j-v[i]]*w[i]);//预处理后可以进行乘法运算
            }
        }

        for(i=sum;i>=0;i--)
        {
            if((1-dp[i]) <= p)//倒着查找,如果发现符合判断的就终止遍历
                break;
        }
        printf("%d\n",i);
    }
    return 0;
}
View Code

 

posted @ 2016-08-04 19:49  声声醉如兰  阅读(123)  评论(0)    收藏  举报