HDU 2955(01背包)

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #define sc(x) scanf("%d",&(x))
 6 #define pf(x) printf("%d\n", x)
 7 #define CL(x, y) memset(x, y, sizeof(x))
 8 #define max(a, b) (a > b ? a : b)
 9 using namespace std;
10 const int MAX = 105;
11 struct node     //设置为背包问题,结构体
12 {
13     int p;
14     double w;
15 }bag[MAX];
16 double dp[MAX*MAX], P;//被抓的概率
17 int m, T, i, j, N;
18 int main()
19 {
20     sc(T);
21     while(T--)
22     {
23         m = 0;
24         scanf("%lf%d",&P, &N);
25         for(i=0; i<N; i++)
26         {
27             scanf("%d%lf",&bag[i].p,&bag[i].w);
28             m += bag[i].p;
29         }
30         CL(dp, 0);
31         dp[0] = 1;
32         for(i = 0; i < N; i++)
33             for(j = m; j >= bag[i].p; j--)
34                 dp[j] = max(dp[j], dp[j-bag[i].p]*(1-bag[i].w));
35         for(i = m; i>=0; i--)
36         {
37             if(dp[i] > 1-P)
38             {
39                 pf(i);
40                 break;
41             }
42         }
43     }
44     return 0;
45 }
View Code

思路1:假设总共抢了j元钱,被抓概率为DP[j],这j元钱里是否抢了第i个个银行,假设第i个银行有value[i][0]元,被抓的概率为value[i][1],所以DP[j] = min ( DP[j] , 1- ( 1-DP[j-value[0]] ) * ( 1-value[i][1] ) ).(设置value[][0]、value[][1])

思路2:最重要的是找动态转移方程,可以将所有银行里的钱看作背包容量,每一家银行的钱看作重量,不被抓到的概率看作价值,则转移方程为:dp[ j ]=max( dp[ j ] , dp[  j - bag[ i ].v]*( 1- bag[ i ].p ) );

posted @ 2015-02-27 21:16  PastLIFE  阅读(121)  评论(0编辑  收藏  举报