hdu2955 01背包 状态转化
一眼看过去就是01背包 但是如果按照普通状态转移的话 无法存储 于是就想到换状态
所有银行的钱为状态 存储不被抓的概率
设盗取第i家银行的概率是Pi, 盗取第i家银行逃跑的概率是Ri
则 Pi = 1 - Ri
且盗取多家(i家)银行被抓的概率 PPi = 1 - (R1*R2*R3*...*Ri), 这中间有个转换过程
当前的概率基于前一种状态的概率,即偷n家银行而不被抓的概率等于偷n-1家银行不被转的概率乘以偷第n家银行不被抓的概率。
用dp[i]表示偷价值为 i 时不被抓的概率,则状态转移方程为:
dp[j] = max(dp[j] , dp[j-m[i]] * (1-p[i]));
#include<iostream>
#include<string.h>
#define ll long long
#define max(a,b) a>b?a:b
using namespace std;
int m[105];double p[105];
double dp[10005];
int main()
{
int t;scanf("%d",&t);
while(t--)
{
int n,sum=0;double M;
scanf("%lf%d",&M,&n);
for(int i=1;i<=n;i++)
{
scanf("%d%lf",&m[i],&p[i]);
sum+=m[i];
}
memset(dp,0,sizeof(dp));
dp[0]=1;
for(int i=1;i<=n;i++)
for(int j=sum;j>=m[i];j--)
{
dp[j]=max(dp[j],dp[j-m[i]]*(1-p[i]));
}
for(int j=sum;j>=0;j--)
if(dp[j]>1-M)
{
printf("%d\n",j);
break;
}
}
return 0;
}