题目:
搜索 CodeForces
1489 蜥蜴和地下室
1 秒 131,072 KB 10 分 2 级题
哈利喜欢玩角色扮演的电脑游戏《蜥蜴和地下室》。此时,他正在扮演一个魔术师。在最后一关,他必须和一排的弓箭手战斗。他唯一能消灭他们的办法是一个火球咒语。如果哈利用他的火球咒语攻击第i个弓箭手(他们从左到右标记),这个弓箭手会失去a点生命值。同时,这个咒语使与第i个弓箭手左右相邻的弓箭手(如果存在)分别失去b(1 ≤ b < a ≤ 10)点生命值。
因为两个端点的弓箭手(即标记为1和n的弓箭手)与你相隔较远,所以火球不能直接攻击他们。但是哈利能用他的火球攻击其他任何弓箭手。
每个弓箭手的生命值都已知。当一个弓箭手的生命值小于0时,这个弓箭手会死亡。请求出哈利杀死所有的敌人所需使用的最少的火球数。
如果弓箭手已经死亡,哈利仍旧可以将他的火球扔向这个弓箭手。
输入
第一行包含3个整数 n, a, b (3 ≤ n ≤ 10; 1 ≤ b < a ≤ 10),第二行包含n个整数——h1,h2,…,hn (1 ≤ hi ≤ 15), hi 是第i个弓箭手所拥有的生命力。
输出
以一行输出t——所需要的最少的火球数。
输入样例
3 2 1
2 2 2
输出样例
3
code is from https://www.cnblogs.com/geloutingyu/p/6298396.html
#pragma comment(linker, "/STACK:10240000,10240000")
#include <cstdio>
#include <iostream>
#include <algorithm>
#include <cmath>
#include <cstring>
#include <map>
#include <set>
#include <vector>
#include <stack>
#include <queue>
#include <cstdlib>
using namespace std;
#define ll long long
#define INF 0x3f3f3f3f
const double pi = acos(-1.0);
const int N=1e3+10;
const int mod = 1e9 + 7;
#define inf 0x3f3f3f3f
int gg[50],ans=inf, n, a, b;
void dfs(int pos,int num)
{
int cnt=0,cc=0;
if(pos == n) //*** 到达第n个人时返回并更新攻击次数
{
ans = min(ans, num);
return ;
}
if(gg[pos-1]<0) //*** 只有前一个人死了之后才能向后移动
{
dfs(pos+1,num);
}
if(gg[pos-1]>=0)//***只处理大于等于零的情况
{
cnt=gg[pos-1]/b+1;
gg[pos-1]-= b*cnt;
gg[pos] -=a*cnt;
gg[pos+1]-=b*cnt;
dfs(pos+1,num+cnt);
gg[pos-1]+=b*cnt;//*** 注意回溯时要将前面改变的量复原
gg[pos]+=a*cnt;
gg[pos+1]+=b*cnt;
}
cc= gg[pos]/a+1;
if(cc>cnt && gg[pos]>=0)//*** 如果此时pos-1已死,而pos还活着,我们可
//以选择直接将其杀死再移向下一个或者直接移向下一位
//当消灭pos-1位置的次数可以在cnt和cc之间时,暴搜找到最合适的次数
{
for(int i=cnt+1;i<=cc;i++)
{
gg[pos-1]-=b*i;
gg[pos]-=a*i;
gg[pos+1]-=b*i;
dfs(pos+1,num+i);
gg[pos-1]+=b*i;
gg[pos]+=a*i;
gg[pos+1]+=b*i;
}
}
return ;
}
int main()
{
int num=0;
cin >> n >> a >>b;
for(int i=1;i<=n;i++)
{
cin>>gg[i];
}
int cnt=gg[1]/b+1;
num+=cnt;
gg[1]-=b*cnt;
gg[2]-=a*cnt;
gg[3]-=b*cnt;
if(gg[n]>=0)
{
cnt = gg[n]/b+1;
num+=cnt;
gg[n-2]-=b*cnt;
gg[n-1]-=a*cnt;
gg[n]-=b*cnt;
}
dfs(2,0);
if(ans == inf)
{
ans = 0;
}
cout << ans+num <<endl;
return 0;
}