51nod 1489 蜥蜴和地下室 (DFS)

哈利喜欢玩角色扮演的电脑游戏《蜥蜴和地下室》。此时,他正在扮演一个魔术师。在最后一关,他必须和一排的弓箭手战斗。他唯一能消灭他们的办法是一个火球咒语。如果哈利用他的火球咒语攻击第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;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值