HDU2955Robberies (0-1背包问题)

题目大意:

       一个人要抢劫银行,在保证被抓概率小于某个预设的概率值时,尽可能抢到更多的钱。

输入:第一行是一个整数t,代表测试用例的个数

           接下来第一行是一个小数P和一个整数N,N代表银行的个数,P代表概率的上限。

           接下来N行,每行两个数,第一个整数代表该银行的钱数,第二个小数代表被抓的概率。

输出:输出每种情况能得到的最大的钱数。


解题思路:

        典型的0-1背包问题,但刚联系背包问题不久,刚看到题目按照正常的0-1背包问题去考虑,发觉背包的空间是小数,没有办法进行,考虑换种思路。

        将N个银行的总钱数看做是被背包空间,每个银行的钱数看成是重量,抢劫每个银行不被抓的概率为价值,因而得到状态转移方程如下:

dp[j]=max(dp[j],dp[j-bank[i].money]*(1-bank[i].p));(其中dp[j]表示抢劫得到的钱数为j时不被抓的概率。


代码如下:

# include 
# include 
using namespace std;

struct node
{
	int money;
	double p;
}bank[10002];

double max(double a,double b)
{
	if(a>=b)
		return a;
	else
		return b;
}

double dp[10002];

int main()
{
	freopen("input.txt","r",stdin);
	int t;
	scanf("%d",&t);
	while(t--)
	{
		double posibility;
		int n;
		scanf("%lf %d",&posibility,&n);
		int i,j,money;
		money=0;
		for(i=0;i=bank[i].money;j--)
			{
				dp[j]=max(dp[j],dp[j-bank[i].money]*(1-bank[i].p));
			}
		}
		for(i=money;i>=0;i--)
			if(dp[i]>=(1-posibility))
			{
				printf("%d\n",i);
				break;
			}
	}
	return 0;
}


你可能感兴趣的:(背包问题)