題意:題目的大概意思是說一我的想去強銀行,但他又怕被抓,但他經過觀察計算出了在每一個銀行被抓的機率,最後他提出若是他能承受最大被抓的機率,如今他想知道,在他能忍受的狀況下,他能搶得的最大金額。php
題解:這一題屬於0-1揹包的變種題,它與那些常規的題目的不一樣之處主要體如今以下方面:ios
(1)在普通的0-1揹包問題中只要肯定了:volume與value變量,下面就比較方便作了,但這一題有點改變,咱們應該用每一個銀行打算搶多少錢的總數你來作volume變量。數組
(2)一般的0-1揹包問題須要咱們直接求題目問咱們的最大值,而在這裏須要咱們從另一個方面來求它的最大值 spa
(3)通常的0-1揹包問題中dp數組中通常存貯的是咱們要求的屬性值,這一題咱們要求的屬性值是他能搶到的最大金額,而在這裏若是這樣作的話,可能會比較麻煩,因此這裏使用它來存儲在搶到j的時候的逃脫機率,是一個double類型的值。code
(4)最後遍歷輸出的時候,當(1-dp[i]<=P)的時候,表示他在能承受的範圍內,能搶到的最大金額爲i,遍歷整個數組,取最大值便可。blog
代碼:ci
1 #include<iostream> 2 #include<algorithm> 3 #include<cstring> 4 using namespace std; 5 int main(){ 6 int T; 7 double P; 8 int N; 9 cin>>T; 10 while(T--){ 11 scanf("%lf%d",&P,&N); 12 int M[20000]={0}; 13 double Pj[20000]={0}; 14 int sum=0; 15 for(int i=1;i<=N;i++){ 16 scanf("%d %lf",&M[i],&Pj[i]); 17 sum=sum+M[i]; 18 }//數據輸入完畢 19 double dp[200000]={0}; 20 dp[0]=1;//搶了 0 萬元 成功逃跑的機率爲 1 21 for(int i=1;i<=N;i++){ 22 for(int j=sum;j>=M[i];j--){ 23 dp[j]=max(dp[j],dp[j-M[i]]*(1-Pj[i])); 24 } 25 } 26 int ans=0; 27 for(int i=sum;i>=0;i--){ 28 if(1-dp[i]<=P){ 29 ans=max(ans,i); 30 break; 31 } 32 } 33 cout<<ans<<endl; 34 } 35 return 0; 36 }