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
题解:由于 1 和 n 不能直接攻击,所以先直接攻击 2,n-1,将他们消灭,然后从 2 开始搜索到 n.
#include<set>
#include<map>
#include<list>
#include<queue>
#include<stack>
#include<math.h>
#include<vector>
#include<bitset>
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define eps (1e-8)
#define MAX 0x3f3f3f3f
#define u_max 1844674407370955161
#define l_max 9223372036854775807
#define i_max 2147483647
#define re register
#define pushup() tree[rt]=tree[rt<<1]+tree[rt<<1|1]
#define nth(k,n) nth_element(a,a+k,a+n); // 将 第K大的放在k位
#define ko() for(int i=2;i<=n;i++) s=(s+k)%i // 约瑟夫
using namespace std;
inline int read(){
char c = getchar(); int x = 0, f = 1;
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' & c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
typedef long long ll;
const double pi = atan(1.)*4.;
const int M=1e3+5;
const int N=1e6+5;
int h[M],n,a,b,ans=i_max;
void dfs(int x,int num){ // x 指当前要直接攻击的编号 num 目前的攻击次数(2 - n)
if(x==n){
ans=min(ans,num);
return ;
}
if(h[x-1]<0) // 从当前位置移动到 下一个位置,充要条件是 h[x-1]<0
dfs(x+1,num);
int time1=0;
if(h[x-1]>=0){ // 要将 x-1位置消灭,最少需要 攻打几次 x 位置的士兵
time1=h[x-1]/b+1;
h[x-1]-=time1*b;
h[x]-=time1*a;
h[x+1]-=time1*b;
dfs(x+1,num+time1);
h[x-1]+=time1*b;
h[x]+=time1*a;
h[x+1]+=time1*b;
}
int time2=h[x]/a+1; // time2 为将 x 位置的士兵消灭,需要 time2 次直接攻击
if(h[x]>=0&&time2>time1){ // 要将 x-1 位置士兵消灭,只要攻打 x 位置士兵 [time1,time2]次,就可以了。
for(int i=time1+1;i<=time2;i++){
h[x-1]-=b*i;
h[x]-=a*i;
h[x+1]-=b*i;
dfs(x+1,num+i);
h[x-1]+=b*i;
h[x]+=a*i;
h[x+1]+=b*i;
}
}
return ;
}
int main(){
scanf("%d %d %d",&n,&a,&b);
for(int i=1;i<=n;i++)
scanf("%d",&h[i]);
int sum=h[1]/b+1; // 消灭 1 号
h[1]-=sum*b;
h[2]-=sum*a;
h[3]-=sum*b;
if(h[n]>=0){
int sum1=h[n]/b+1; // 消灭 n 号
h[n]-=sum1*b;
h[n-1]-=sum1*a;
h[n-2]-=sum1*b;
sum+=sum1;
}
dfs(2,0);
printf("%d\n",ans+sum);
return 0;
}