现在的位置: 首页 > 综合 > 正文

hdu 2955 Robberies(01背包)

2018年01月12日 ⁄ 综合 ⁄ 共 811字 ⁄ 字号 评论关闭

题目:要去偷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;
}

抱歉!评论已关闭.