题目大意:Roy去抢银行,问在给定的被抓住的概率下,Roy可以抢的金钱数额最多,且小于给定概率
输入:第一行输入一个整数 T,为案例数,每组案例第一行输入给定概率 P 和银行数目 N,接下来 N 行输入该银行的钱数 Mj 和被抓概率 Pj
思路分析:值得注意的一点是,要将可得金钱数目当作价值,将每个银行的金钱数当作花费,状态转移方程为 dp [ j ] = max ( dp [ j ] , dp [ j - Mi ] * ( 1 - Pi ) ),其中 dp [ j ] 表示在当前容量j 下,Roy不被抓到的概率最大 && Roy可以抢到的最大钱数 (不被抓到的概率最大==被抓到的概率最小),还有一点需要注意的是,因为计算概率时是用乘法,所以 dp [ 0 ] =1.0 , dp [ i ] = 0 ( i = 1 , 2 , 3 ......)
抢 n 个银行不被抓到的概率计算公式为 (1 - P0 )* ( 1 - P1 ) * ...... *( 1 - Pn ) 。
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=105;
int money[maxn];
double pro[maxn];
double dp[10005];
int main()
{
int t;
cin>>t;
while(t--)
{
memset(dp,0,sizeof(dp));
double p;
int n,sum=0,i;
cin>>p>>n;
for(i=1;i<=n;i++)
{
cin>>money[i]>>pro[i];
sum+=money[i];
pro[i]=1-pro[i];
}
p=1-p;
dp[0]=1.0;
for(i=1;i<=n;i++)
{
for(int j=sum;j>=money[i];j--)
dp[j]=max(dp[j],dp[j-money[i]]*pro[i]);
}
for(i=sum;i>0;i--)
if(dp[i]>p)
break;
cout<<i<<endl;
}
return 0;
}