码迷,mamicode.com
首页 > 其他好文 > 详细

Dynamic Programming - HDU

时间:2015-03-14 13:49:05      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:

最近主要刷一下动态规划专题,题目来自于HDU。

 

HDU 2955

这是一道概率DP,我第一次的想法是把概率P乘以100,变成一个背包然后做0-1背包,后来发现这样做是错误的。

原因:概率应该是相乘,而不是相加。

后来看了题解想到了另外一种方法,使用逃脱概率来计算,用f[j]表示偷走j价值后逃脱的概率。易知,多次逃脱概率为每次逃脱概率相乘。

由于要计算逃脱概率,我们可以在读入的时候就把可能被逮捕的概率P变成可能逃脱的概率1 - P。

这样,状态转移方程为:f[j] = max(f[j - pValue[i]] * pCost[i], f[j])。其中pValue[i]表示第i个银行的价值,pCost[i]表示偷第i个银行逃脱的概率。

这时候,我们还需要考虑一个转移条件,如果f[j - pValue[i]]没有被更新过,那么是不能转移过来的。因为暂时没有一个状态可以偷到j - pValue[i]价值的物品。

接下来,我们要考虑一下初始条件,很显然f[0] = 1,因为不偷任何东西,就不会被逮捕,逃脱的概率就为1。其余f[j] = -1,其中j ≠ 0,表示暂时没有一个状态可以偷到j价值的物品。

最后扫一遍f[j],满足1 - f[j] <= P的最大下标j为满足题设条件的答案。

#include <iostream>
#include <memory.h>

using namespace std;

const int MAX = 10240;

int pValue[MAX];
double pCost[MAX], f[MAX];

int main()
{
	int T, M, V;
	double P;
	cin >> T;
	for(int k = 1; k <= T; k++)
	{
		f[0] = 1; V = 0;
		for(int i = 1; i < MAX; i++)
		{ f[i] = -1; }
		cin >> P >> M;
		for(int i = 1; i <= M; i++)
		{
			cin >> pValue[i] >> pCost[i];
			pCost[i] = 1 - pCost[i];
			V += pValue[i];
		}
		for(int i = 1; i <= M; i++)
		{
			for(int j = V; j >= pValue[i]; j--)
			{
				if(f[j - pValue[i]] != -1)
				{ f[j] = max(f[j - pValue[i]] * pCost[i], f[j]); }
			}
		}
		int ans = 0;
		for(int i = 0; i <= V; i++)
		{
			if(1 - f[i] <= P)
			{ ans = i; }
		}
		cout << ans << endl;
	}
	return 0;
}

接触的第一道概率DP,发现DP非常的灵活,自己还有很多东西要学。 

2015年3月14日

 

【未完待续...】

Dynamic Programming - HDU

标签:

原文地址:http://www.cnblogs.com/Ivy-End/p/4337406.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!