这一题,很有趣味。
首先,如果是按照照常的思路,在内层for循环,没办法遍历背包容量(概率),概率是double/float型的数据。
所以,将价值看成背包容量,在寻找可行的最大的价值时,将价值从大到小遍历,出现满足的概率条件时,便可以结束,此时的背包容量(价值),就是最终结果。
另外,注意,这么多银行中只要有一个银行抓住了他,就没有逃脱成功。
//HDU 2955
#include<iostream>
#include<cstring>
#include<algorithm>
#include<set>
#include<queue>
#include<cmath>
#include<stack>
using namespace std;
double pro[105];
int money[105];
double dp[10005];
int main()
{
int t;
double p;
int n;
scanf("%d",&t);
while(t--)
{
scanf("%lf%d",&p,&n);
memset(dp,0,sizeof(dp));
// memset(pro,0,sizeof(pro));
// memset(money,0,sizeof(money));
long long sum=0;
double tempp;
for(int i=0;i<n;i++)
{
scanf("%d%lf",&money[i],&tempp);
pro[i]=1-tempp;
sum+=money[i];
}
dp[0]=1;
for(int i=0;i<n;i++)
{
for(int j=sum;j>=money[i];j--)
{
// printf("dp[%d]=%lf dp[%d-%d]*%lf=%lf\n",j,dp[j],j,money[i],pro[i],dp[j-money[i]]*pro[i]);
dp[j]=max(dp[j],dp[j-money[i]]*pro[i]);
}
//cout<<endl;
}
for(int j=sum;j>=0;j--)
{
if(dp[j]>1-p)
{
printf("%d\n",j);
break;
}
}
}
return 0;
}
初始化的时候出现了问题,dp[0]=1,不偷不抢任何银行时,一定不会被抓住。
结果我初始化是dp[money[i]]=pro[i],这样是不对的,因为我也可能在money[i]的背包容量时,选择其他的组合,都有可能大于pro[i].所以,动态规划问题,一定要想清楚初始化的条件。
接着,又TLE了一次,,不论怎么优化,都TLE。
无奈,各种翻博客。发现自己的dp[]数组开小了。。。。。