hdu2955_Robberies

http://acm.hdu.edu.cn/showproblem.php?pid=2955

dp[i] 表示偷了 i 块钱时不被抓的概率

dp[j] = max(dp[j], dp[j - m[i]] * (1 - p[i]))
(注意:因为是概率事件,在抢了第一家银行后不被抓的情况下再去抢第二家银行,所以要 *(1-p[i])而不是 + )


01 #include <cstdio>
02 #include <cstring>
03 using namespace std;
04
05 const int N = 110;
06 double dp [N *N ], p [N ];
07 int m [N ];
08 int t , n;
09 double P;
10
11 double max( double a , double b)
12 {
13     return a > b ? a : b;
14 }
15
16 int main()
17 {
18     for ( scanf( "%d" , & t); t; t --)
19     {
20         scanf( "%lf%d" , &P , &n);
21         P = 1 - P;
22         int sum = 0;
23         for ( int i = 1; i <= n; i ++)
24         {
25             scanf( "%d%lf" , & m [ i ], &p [ i ]);
26             sum += m [ i ];
27         }
28         memset ( dp , 0 , sizeof( dp));
29         dp [ 0 ] = 1;   //不偷钱则绝对不会被抓
30         for ( int i = 1; i <= n; i ++)
31             for ( int j = sum; j >= m [ i ]; j --)
32                 dp [ j ] = max( dp [ j ], dp [ j - m [ i ]] * ( 1 - p [ i ]));
33         for ( int i = sum; i >= 0; i --)
34             if ( dp [ i ] >= P)
35             {
36                 printf( "%d \n " , i);
37                 break;
38             }
39     }
40 }

你可能感兴趣的:(hdu2955_Robberies)