51nod 1489蜥蜴和地下室
1489 蜥蜴和地下室
哈利喜欢玩角色扮演的电脑游戏《蜥蜴和地下室》。此时,他正在扮演一个魔术师。在最后一关,他必须和一排的弓箭手战斗。他唯一能消灭他们的办法是一个火球咒语。如果哈利用他的火球咒语攻击第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
dfs
由于两端不能直接攻击,所以肯定是通过间接攻击,先算出两端需要的火球,然后dfs算出中间的火球。
1 #include <bits/stdc++.h> 2 using namespace std; 3 int ans[15], n, a, b, MIN = 1000000; 4 bool check(){ 5 for(int i = 1; i <= n; i ++) { 6 if(ans[i] >= 0) return false; 7 } 8 return true; 9 } 10 void dfs(int l, int depth) { 11 if(l == n) { 12 MIN = min(MIN, depth); 13 return; 14 } 15 if(ans[l-1] < 0) dfs(l+1,depth); 16 int x = 0, y; 17 if(ans[l-1] >= 0) { 18 x = ans[l-1]/b+1; 19 ans[l-1] -= x*b; 20 ans[l] -= x*a; 21 ans[l+1] -= x*b; 22 dfs(l+1,depth+x); 23 ans[l-1] += x*b; 24 ans[l] += x*a; 25 ans[l+1] += x*b; 26 } 27 y = ans[l]/a+1; 28 if(y > x && ans[l] >= 0) { 29 for(int i = x+1; i <= y; i ++) { 30 ans[l-1] -= i*b; 31 ans[l] -= i*a; 32 ans[l+1] -= i*b; 33 dfs(l+1,depth+i); 34 ans[l-1] += i*b; 35 ans[l] += i*a; 36 ans[l+1] += i*b; 37 } 38 } 39 } 40 int main() { 41 cin >> n >> a >> b; 42 for(int i = 1; i <= n; i ++) scanf("%d", &ans[i]); 43 int cnt = ans[1] / b + 1; 44 ans[1] -= cnt*b; 45 ans[2] -= cnt*a; 46 ans[3] -= cnt*b; 47 if(ans[n] >= 0) { 48 int tmp = ans[n]/b+1; 49 cnt += tmp; 50 ans[n] -= b*tmp; 51 ans[n-1] -= a*tmp; 52 ans[n-2] -= b*tmp; 53 } 54 dfs(2,0); 55 printf("%d\n",MIN+cnt); 56 return 0; 57 }