您的位置:首页 > 其它

51 Nod 1489 蜥蜴与地下室(DFS)

2017-03-05 20:17 429 查看
1489 蜥蜴和地下室


题目来源: CodeForces

基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题


 收藏


 关注

哈利喜欢玩角色扮演的电脑游戏《蜥蜴和地下室》。此时,他正在扮演一个魔术师。在最后一关,他必须和一排的弓箭手战斗。他唯一能消灭他们的办法是一个火球咒语。如果哈利用他的火球咒语攻击第i个弓箭手(他们从左到右标记),这个弓箭手会失去a点生命值。同时,这个咒语使与第i个弓箭手左右相邻的弓箭手(如果存在)分别失去b(1 ≤ b < a ≤ 10)点生命值。

因为两个端点的弓箭手(即标记为1和n的弓箭手)与你相隔较远,所以火球不能直接攻击他们。但是哈利能用他的火球攻击其他任何弓箭手。

每个弓箭手的生命值都已知。当一个弓箭手的生命值小于0时,这个弓箭手会死亡。请求出哈利杀死所有的敌人所需使用的最少的火球数。

如果弓箭手已经死亡,哈利仍旧可以将他的火球扔向这个弓箭手。

Input
第一行包含3个整数 n, a, b (3 ≤ n ≤ 10; 1 ≤ b < a ≤ 10),第二行包含n个整数——h1,h2,...,hn (1 ≤ hi ≤ 15), hi 是第i个弓箭手所拥有的生命力。


Output
以一行输出t——所需要的最少的火球数。


Input示例
3 2 1
2 2 2


Output示例
3






System Message (题目提供者)
http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1489
思路:首先要打死两头的弓箭手,然后DFS搜素打死中间弓箭手的最优。对于第N个弓箭手,要想继续搜素N+1个,就必须使

N-1个小于0,不需要顾及N,所以递归搜素满足N-1小于0的条件即可。

#include<stdio.h>
#include<string.h>
#include<algorithm>
#define INF 0x3f3f3f3f
using namespace std;
int res = 0;    //  打爆首尾需要的次数
int res_2 = INF;//  打爆中间的需要的最少次数
int n, a, b;
int H[11];    //  生命值

void dfs(int N, int ans)
{
//  当到达第n个人时,更新最少的爆破次数,并返回
if (N == n)
{
res_2 = res_2 > ans ? ans : res_2;
return ;
}
//  每次向后搜索都要保证第N-1个为负数
if (H[N - 1] < 0)
{
dfs(N + 1, ans);
}
int times = 0;
//  必须在第N位置爆times次才能保证第N-1个为负数
if (H[N - 1] >= 0)
{
times = H[N - 1] / b + 1;
H[N - 1] -= b * times;
H
-= a * times;
H[N + 1] -= b * times;
dfs(N + 1, ans + times);
H[N - 1] += b * times;
H
+= a * times;
H[N + 1] += b * times;
}
//  只要爆times~times_次都能保证第N-1个为负数
int times_ = H
/ a + 1;
if (H
>= 0 && times_ > times)
{
for (int i = times + 1; i <= times_; i++)
{
H[N - 1] -= b * i;
H
-= a * i;
H[N + 1] -= b * i;
dfs(N + 1, ans + i);
H[N - 1] += b * i;
H
+= a * i;
H[N + 1] += b * i;
}
}
return ;
}

int main()
{
scanf("%d %d %d", &n, &a, &b);
for (int i = 1; i <= n; i++)
{
scanf("%d", &H[i]);
}
//  打爆第1个
int times = H[1] / b + 1;
res += times;
H[1] -= b * times;
H[2] -= a * times;
H[3] -= b * times;
//  打爆第n个
if (H
>= 0)
{
times = H
/ b + 1;
res += times;
H
-= b * times;
H[n - 1] -= a * times;
H[n - 2] -= b * times;
}
dfs(2, 0);
//  保证res_2是有效次数
if (res_2 == INF)
{
res_2 = 0;
}
printf("%d\n", res + res_2);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: