HDU-2955(01背包)

来源:互联网 发布:windows 2000 编辑:程序博客网 时间:2024/05/21 22:59

DP46题的第一步!

题意不是很难懂,但是还是读错了。。。

需要注意的是,概率是浮点数,直接被好像不行,所以还是找满足条件的最大的数。

所以状态方程就是 dp[j] = max ( dp[j] , dp[ j - w[i] ] * ( 1-v[i] ) );

这里的w数组是银行的钱数,v是被抓的概率,dp数组代表偷盗j数量的钱时不被抓的概率


代码:

#include <iostream>#include <cstdio>#include <cstring>#include <stdio.h>using namespace std;const int maxn = 10000+10;int T;int n;double dp[maxn];int w[maxn];double v[maxn];double p;int main(){    cin >> T;    while(T--)    {        cin >> p >> n;        int max_m = 0;        memset(dp,0,sizeof(dp));        memset(w,0,sizeof(w));        memset(v,0,sizeof(v));        for(int i=0;i<n;i++)        {            cin >> w[i] >> v[i];            max_m+=w[i];            //cout << w[i] <<" " <<v[i] <<endl;         }        dp[0] = 1;//        for(int i=1;i<10000;i++)//        {//            dp[i] = -1;//        }        for(int i=0;i<n;i++)        {            for(int j=max_m;j>=w[i];j--)            {                dp[j] = max ( dp[j] , dp[j-w[i]]*(1-(v[i])));               // cout << dp[j] <<endl;            }        }        int Max_m = 0;        for(int i=max_m;i>=0;i--)        {            if(dp[i]>1-p)            {                cout << i <<endl;                break;            }        }        //cout << max_m <<endl;    }    return 0;}