题目:要去偷N家银行,要求被抓的概率小于P,每家银行可以偷mi元,被抓的概率为pi, 问在不被抓的情况下,能最多偷多少钱?
分析:dp[i][j],为偷前i家银行,得到j元,没被抓的最大概率。转移方程为:dp[j]=max{ dp[j], dp[j-mi]*pi }
注意初始化:偷0元,不被抓的概率为1,既然偷了,不被抓的概率为0......
#include<iostream> #include<cstdio> using namespace std; int main() { int t; scanf("%d",&t); while(t--) { double p; int n,i,j; int m[120],sum=0; double dp[10010],po[120];//***吧po数组的类型搞错了 //dp[i][j]代表抢前i家银行,所得价值为j,不被捕的最小概率; //memset(dp,0,sizeof(dp)); scanf("%lf %d",&p,&n); for(i=1;i<=n;i++) { scanf("%d %lf",&m[i],&po[i]); sum+=m[i]; } //初始化 for(int i=1;i<=sum;i++) dp[i]=0;//既然偷了,不被抓的概率为0; dp[0]=1.0;//偷0元 ,不被抓的概率为1; for(i=1;i<=n;i++) { /*for(int j=m[i];j<=10000;j++) dp[j]=min(dp[j],dp[j-m[i]]*(1.0-po[i]));*/ for(int j=sum;j>=m[i];j--) dp[j]=max(dp[j],dp[j-m[i]]*(1.0-po[i])); } int ans=0; for(int i=0;i<=sum;i++) if(dp[i]>=(1.0-p) && i>ans) ans=i; printf("%d\n",ans); } system("pause"); return 0; }