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 }
思路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 ) );
时间: 2024-10-01 22:33:52