hduoj_2955(01背包变形,动态规划)

这道题关于概率的部分我理解了。

另一点就是转化成01背包的问题。

我是这么想的。

01背包dp时是求在一定容量下的最大价值。

这道题dp时是求获得一定金钱时的最大逃跑概率。

感觉和01背包还是有一点差别。虽然代码写起来很像。


先记录在这里。希望有一天能够彻底的理解这个问题。


附上代码。

#include <stdio.h>
#include <string.h>

int money[101];
float risk[101];
float dp[10001];

int main()
{
	int T;
	scanf("%d", &T);

	int N;
	float P;
	int i, j;
	int sum;

	while (T--)
	{
		scanf("%f %d", &P, &N);

		P = 1 - P;

		sum = 0;
		for (i = 1; i <= N; i++)
		{
			scanf("%d %f", &money[i], &risk[i]);
			sum += money[i];
			risk[i] = 1 - risk[i];
		}
			
		/*
		关于概率计算
		题目中给出的是偷窃每家银行被抓的概率
		要求的是整体被抓的概率
		只要偷一家银行时被抓 就是被抓了 有多种情况 都列出来很麻烦
		因此可以换一个角度考虑
		不被抓只有一种情况,就是偷所有的银行都不被抓 求出这个概率
		再用1减去这个概率 就是整体被抓的概率
		*/
		memset(dp, 0, sizeof(dp));
		dp[0] = 1;
		for (i = 1; i <= N; i++)
		{
			for (j = sum; j >= money[i]; j--)
				dp[j] = dp[j] > (dp[j - money[i]] * risk[i]) ? dp[j] : (dp[j - money[i]] * risk[i]);

			// to help myself understand the question
			/*for (j = 0; j <= sum; j++)
				printf("%f ", dp[j]);
			printf("\n");*/
		}

		for (i = sum; i >= 0; i--)
		{
			if (dp[i] >= P)
			{
				printf("%d\n", i);
				break;
			}
				
		}

	}
	return 0;
}





猜你喜欢

转载自blog.csdn.net/qq_32862515/article/details/80717953
今日推荐