哈利喜欢玩角色扮演的电脑游戏《蜥蜴和地下室》。此时,他正在扮演一个魔术师。在最后一关,他必须和一排的弓箭手战斗。他唯一能消灭他们的办法是一个火球咒语。如果哈利用他的火球咒语攻击第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
/*先将第一个和最后一个敌人保证杀死,接下来按顺序搜索其他,
并保证搜索x+1个时,x-1必须已经被杀死,因为如果x没死,还可以被x+1溅伤,而第x-1个无法再受伤害
*/
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int h[20];
int n, a, b, ans1, ans2;
void dfs(int x, int ans)
{
if(x == n)//如果搜索到第n个,则证明全部被杀死
{
ans2 = min(ans2, ans);
return ;
}
if(ans > ans2)//剪枝,如果还没到最后,所用火球已经超过之前,则不用继续搜索
{
return ;
}
if(h[x-1] < 0)
{
dfs(x+1, ans);
}
int t = 0;
if(h[x-1] >= 0)
{
t = h[x-1] / b + 1;
h[x-1] -= b * t;
h[x] -= a * t;
h[x+1] -= b * t;
dfs(x+1, ans+t);
h[x-1] += b * t;
h[x] += a * t;
h[x+1] += b * t;
}
int t2 = h[x] / a + 1;
//如果t个火球已经杀死第x-1个敌人,但第x个敌人依旧活着,我们可以选择继续攻击第x个敌人或者攻击下一个敌人来溅伤第x个敌人
if(h[x] >= 0 && t2 > t)
{
for(int i = t+1; i <= t2; i++)
{
h[x-1] -= i * b;
h[x] -= i * a;
h[x+1] -= i * b;
dfs(x+1, ans+i);
h[x-1] += i * b;
h[x] += i * a;
h[x+1] += i * b;
}
}
return ;
}
int main()
{
int i, times;
scanf("%d %d %d", &n, &a, &b);
memset(h, -1, sizeof(h));
for(i = 1; i <= n; i++)
{
scanf("%d", &h[i]);
}
ans1 = 0;
ans2 = 0xffff;
if(h[1] >= 0)//先求打爆第一个敌人所需的火球
{
times = h[1] / b + 1;
ans1 += times;
h[1] -= times * b;
h[2] -= times * a;
h[3] -= times * b;
}
if(h[n] >= 0)//求打爆最后一个敌人所需的火球
{
times = h[n] / b + 1;
ans1 += times;
h[n] -= times * b;
h[n-1] -= times * a;
h[n-2] -= times * b;
}
dfs(2, 0);//从第二个开始从前往后搜索
printf("%d\n", ans1+ans2);
return 0;
}