HDU 2955

  这是一道01背包的问题,但是有一个地方我没有想到,所以花了很多时间。

  题目给了每个银行的钱和被抓的概率,由于要抢尽量多的钱,所以要保证尽量不被抓,而抢多个银行之后不被抓的概率是抢每一个银行不被抓的概率之积,我竟然把这一点给忘了!导致我走了许多弯路,思路不能太死啊!dp[]表示抢到下标所对应的钱时,此时不被抓的概率,题目给出了最终不能高于被抓概率P,不被抓的概率就不能低于(1-P),所以最后只需要逆序遍历dp,找到第一个大于等于1-P的dp[i],就能够保证i最大,即抢到的钱最多。

 

#include<stdio.h>
#include<string.h>
#define MAX_LMT 10000
float max(float,float);
int main()
    {
    int t,money[MAX_LMT];
    float prob[MAX_LMT],dp[MAX_LMT];
    scanf("%d",&t);
    while(t--)
    {
    float P;
    int n,i,j,total=0;
    scanf("%f%d",&P,&n);
    for(i=1;i<=n;i++)
    {
        scanf("%d%f",&money[i],&prob[i]);
        total+=money[i];
    }
    memset(dp,0,sizeof(dp));
    dp[0]=1;
    for(i=1;i<=n;i++)
    {
        for(j=total;j>=money[i];j--)
        {
        dp[j]=max(dp[j],dp[j-money[i]]*(1-prob[i]));
        }
    }
    for(i=total;i>=0;i--)
    {
        if(dp[i]>=(1-P))
        {
        printf("%d\n",i);
        break;
        }
    }
    }
    return 0;
}
float max(float x,float y)
{
    return x>y?x:y;
}
posted @ 2012-07-28 20:29  等待电子的砹  阅读(1185)  评论(0编辑  收藏  举报