解决SPOJ Diehard的正确方法是什么?
What is the correct approach to solve SPOJ DIEHARD?
我试图在spoj https://www.spoj.pl/problems/diehard/上解决一个练习问题。但是,我的贪婪方法都导致错误的答案和递归对最坏的情况来说太慢了。有人可以告诉如何解决这个问题吗?我正在寻找有人指向正确的方向。
游戏很简单。最初,您拥有" H"量的健康和" A"装甲量。在任何瞬间,您都可以住在三个地方中的任何一个 - 火,水和空气。每次单位之后,您都必须改变自己的生活地点。例如,如果您目前居住在火中,则可以踏入水或空气。
- 如果您踏入空中,您的健康状况会增加3,并且您的装甲增加2
- 如果您踏入水中,您的健康状况会降低5,盔甲降低10
如果您着火了,您的健康状况会减少20,而您的装甲增加了5如果您的健康或装甲变为< = 0,您将立即死亡
找到您可以生存的最长时间。
输入:
第一行由整数T组成,即测试用例的数量。对于每个测试案例,将有两个代表初始健康h和初始装甲a的正整数。
输出:
对于每个测试案例,找到您可以生存的最长时间。
好吧,首先尝试通过贪婪的方法解决它。很明显,由于增加了装甲和健康,空气是最佳选择,但您只能交替去空中。因此,每个奇数(即1,3,5 ...)的移动都将是播出的。现在我们必须决定如何处理偶数?
所以我们有两种选择射击还是水?我们必须是合理的,并选择这样的举动,以保持H和A高于0。t您的健康> 0。因此,如果H> 5和a> 10选择水。
现在,如果我们没有装甲但健康状况足够怎么办?在这种情况下,我们别无选择,只能跳火。
所以现在我们有了一种贪婪的方法:
因此,如果我们有足够的H和A,我们将去水。否则,如果H足够足够并且A还不够,请点燃。否则,已经结束了!
这是实现的界面链接:http://ideone.com/rkobnk
#include<stdio.h>
int main(){
long long int x,i,a,b,t,h,arm;
scanf("%lld",&x);
for(i=0;i<x;i++){
scanf("%lld %lld",&a,&b);
if(a==0||b==0)
printf("0n");
else{
t=1;
h=a+3;
arm=b+2;
while(1){
if(h>5&&arm>10){
h=h-2;
arm=arm-8;
t=t+2;
}else if(h>20&&arm<=10){
h=h-17;
arm=arm+7;
t=t+2;
}else {
printf("%lldn",t);
break;
}
}
}
}
return 0;
}
这是通过分析进行操作的另一种方法:
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进行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;
无论哪种情况,都使用基本高中代数来简化不平等/方程。
i通过使用动态进程来完成。DP [Health] [Armour] [Air/Fire/Water] - 如果您从这种情况开始然后,复发状况简单地变成DP [Health] [Armour] [空气/消防/水] = 1 下一个状态的最大显而易见的基本情况是他无处可去的时候,所以答案变为零。
您是否尝试过DFS?状态是(空气|火|水,h,a)的元组。这有:
3 * 1000 * 1000 = 3,000,000 game states
在上面做DFS并找到最高的动作。(即将所有内容都设置为-1,然后将初始状态设置为0,然后将DFS从0到所有可及的位置)
- 为不同配置设置MSVC_RUNTIME_LIBRARY的正确方法是什么
- 在C++中,将大的无符号浮点数四舍五入为整数的最佳方法是什么
- 实现无开销push_back的最佳方法是什么
- C++从另一个类访问公共静态向量的正确方法是什么
- 在 c++ 中拥有一组结构的正确方法是什么?
- 通过JNI传递数据数组的最快方法是什么
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 使用不同的CRT将新的C++代码与旧的(二进制)组件隔离开来的最佳方法是什么
- 当无法使用模板和宏时,生成类型变体C++代码的最简单方法是什么?
- 在另一个类视图中添加最多2个图表的正确方法是什么
- 在C++中样板"冷/never_inline"错误处理技术的最佳方法是什么?
- 在 c++ 中对类中的 c 字符串动态数组进行排序的最佳方法是什么?
- 在C++中包含原型文件的正确方法是什么?
- 在 OpenCV C++ 中估计基本矩阵之前对相应点进行归一化的正确方法是什么?
- 在PostgreSQL中根据它们的ID选择大量行的最快方法是什么?
- 在OSX上使用CMake将Adobe的XMP工具包构建为共享库的最简单方法是什么?
- 将一系列整数放入类的最佳方法是什么?
- 从长整整转换为uint64_t的推荐方法是什么?
- 将此布尔值传递给此函数的最有效方法是什么?
- 通过比较C++中的行在 txt 文件中搜索的最简单方法是什么?