我试图在SPOJ https://www.spoj.pl/problems/DIEHARD/上解决练习题。 然而,我的贪婪方法导致错误的答案和递归对于最坏的情况来说太慢。任何人都可以告诉如何解决这个问题?我正在寻找有人指出我正确的方向。
游戏很简单。你最初有'H'的健康和'A'量的护甲。在任何时刻,您都可以居住在三个地方中的任何一个地方 - 火,水和空气。每个单位时间之后,你必须改变你的生活地点。例如,如果你现在生活在火中,你可以进入水中或空气中。
- 如果你进入空中,你的生命值会提高3点,你的护甲会增加2点
- 如果你踏入水中,你的生命值会降低5点,你的护甲会降低10点 如果你步入火中,你的生命值会降低20点,你的护甲会增加5点
如果您的健康或护甲变为<= 0,您将立即死亡
找出你能活下来的最长时间。
输入:
第一行包含整数t,即测试用例的数量。对于每个测试用例,将有两个正整数代表初始健康H和初始护甲A.
输出:
对于每个测试用例,找到您可以存活的最长时间。
答案 0 :(得分:1)
以下是另一种分析方法:
a = number of times visiting air state
F = number of times visiting fire state
W = number of times visiting water state
M = a + F + W // total moves
// positive
a >= 0
F >= 0
W >= 0
// because of the restriction of moving between states...
a <= F + W + 1
F <= W + a + 1
W <= a + F + 1
// the effect of armor and health...
H < -3a + 5H + 20F
A < -2a + 10W - 5F
最大化M.您可以通过二进制搜索M来完成此操作,或者您可以使用线性编程。
二进制搜索循环:
int ok = 0;
int impossible = 1000000000;
while (impossible - ok > 1)
{
int candidate = ok + (impossible-ok) / 2;
if (check(candidate))
ok = candidate;
else
impossible = candidate;
}
return ok;
在任何一种情况下都使用基本的高中代数来简化不等式/方程式。
答案 1 :(得分:0)
你试过DFS吗?状态是(空气,水,H,A)的元组。这有:
3 * 1000 * 1000 = 3,000,000 game states
对其进行DFS并找到最高动作。 (即将所有内容设置为-1,将初始状态设置为0,然后将DFS从0状态设置为所有可到达位置)
答案 2 :(得分:0)
我通过使用动态编程来完成。 Dp [健康] [护甲] [空气/火/水] - 如果你从这个状态开始你可以活的最长时间 那么经常性的条件就变成了 Dp [健康] [护甲] [空气/火/水] =你可以去的下一个状态的1 +最大值 很明显,基本情况是他无处可去,所以答案就是零。