题目来源:   CodeForces
基准时间限制:1  秒 空间限制:131072  KB 分值:  10   难度:2级算法题
51Nod-1489 蜥蜴和地下室(暴力DFS)_dfs_02  收藏
51Nod-1489 蜥蜴和地下室(暴力DFS)_#include_03  关注

哈利喜欢玩角色扮演的电脑游戏《蜥蜴和地下室》。此时,他正在扮演一个魔术师。在最后一关,他必须和一排的弓箭手战斗。他唯一能消灭他们的办法是一个火球咒语。如果哈利用他的火球咒语攻击第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
51Nod-1489 蜥蜴和地下室(暴力DFS)_#define_04
System Message   (题目提供者)
 
思路:每次从第一个血量大于等于0的弓箭手开始,在dfs之前先把头和尾打爆,并且尽量不直接打爆
,只有这样才能保证用的火球术最少,剩下直接dfs了。N很小,所以可以无脑暴力,
代码里的注释写的很清楚,所以这里不再过多解释。。(网上有DP解法,只怪我太弱,不会用)
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<algorithm>
#include<limits.h>
#include<queue>
#include<stack>
#include<vector>
#include<math.h>
#include<map>
using namespace std;
#define maxn 105
#define inf 0xfffffff  
typedef long long ll;
ll s[maxn],n,a,b,ans=inf,sum;
void dfs(ll x,ll num)//x表示当前弓箭手,num表示当前释放火球术的次数 
{
	if(x==n)
	{
	 ans=min(ans,num);
	 return;
    }
	if(s[x-1]<0)
	dfs(x+1,num);
	ll t=0;
	if(s[x-1]>=0)
	{
	t=s[x-1]/b+1;
	num+=t;
	s[x-1]-=t*b;
	s[x]-=t*a;
	s[x+1]-=t*b;
	dfs(x+1,num);
	num-=t;
	s[x-1]+=t*b;
	s[x]+=t*a;
	s[x+1]+=t*b;
    }
	ll t1=s[x]/a+1;
	if(s[x]>=0 && t1>t)//假如打爆x-1后x还活着,则说明x的血量大于x-1,
	//因此要打爆x,此时打爆x有两种方法,就是直接打爆和通过
	//打爆x+1来打爆x 
	{
		for(int i=t+1;i<=t1;i++)
		{
			num+=i;
			s[x-1]-=i*b;
			s[x]-=i*a;
			s[x+1]-=i*b;
			dfs(x+1,num);
			num-=i;
			s[x-1]+=i*b;
			s[x]+=i*a;
			s[x+1]+=i*b;
		 } 
	}
	return ;
}
int  main()
{
	ll i,j;
	memset(s,0,sizeof(s));
	scanf("%lld%lld%lld",&n,&a,&b);
	for(i=1;i<=n;i++)
	scanf("%lld",&s[i]);
	ll x=s[1]/b+1;//先把头和尾打爆 
	sum+=x;
	s[1]-=x*b;
	s[2]-=x*a;
	s[3]-=x*b;
	if(s[n]>=0)
	{
	   x=s[n]/b+1;
	   sum+=x;
	   s[n]-=x*b;
	   s[n-1]-=x*a;
	   s[n-2]-=x*b;
	}
	dfs(2,0); 
	if(ans==inf)ans=0;
	printf("%lld\n",sum+ans);
}