哈利喜欢玩角色扮演的电脑游戏《蜥蜴和地下室》。此时,他正在扮演一个魔术师。在最后一关,他必须和一排的弓箭手战斗。他唯一能消灭他们的办法是一个火球咒语。如果哈利用他的火球咒语攻击第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
本以为是个贪心的问题,后来才发现这不是一个贪心的问题(其实就是贪心错了好多遍)然后深搜先处理两端,然后在处理中间的。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<math.h>
#include<set>
#include<stack>
#include<queue>
#include<string>
#include<iostream>
#include<vector>
using namespace std;
#define inf 0x3f3f3f3f
int n,a,b,s[1010],zz=inf;
long long ans=0;
void dfs(int x,int num)
{
if(x==n-1)
{
zz=min(num,zz);
return ;
}
int t=0;
if(s[x-1]<0)
dfs(x+1,num);
if(s[x-1]>=0)
{
t=s[x-1]/b+1;
s[x-1]-=t*b;
s[x]-=t*a;
s[x+1]-=b*t;
dfs(x+1,num+t);
s[x-1]+=t*b;
s[x]+=t*a;
s[x+1]+=b*t;
}
int time=s[x]/a+1;
if(time>t&&s[x]>=0)
{
for(int i=t+1; i<=time; i++)
{
s[x-1]-=i*b;
s[x]-=i*a;
s[x+1]-=i*b;
dfs(x+1,num+i);
s[x-1]+=i*b;
s[x]+=i*a;
s[x+1]+=i*b;
}
}
return ;
}
int main()
{
scanf("%d%d%d",&n,&a,&b);
for(int i=0; i<n; i++)
scanf("%d",&s[i]);
int t1=s[0]/b+1;
s[0]-=t1*b;
s[1]-=t1*a;
s[2]-=t1*b;
ans+=t1;
if(s[n-1]>=0)
{
int t2=s[n-1]/b+1;
s[n-1]-=t2*b;
s[n-2]-=t2*a;
s[n-3]-=t2*b;
ans+=t2;
}
dfs(1,0);
if(zz!=inf)
{
ans+=zz;
}
printf("%d\n",ans);
return 0;
}