1. 程式人生 > >(dfs) - 1489 蜥蜴和地下室

(dfs) - 1489 蜥蜴和地下室

1489 蜥蜴和地下室

  1. 1 秒
  2.  
  3. 131,072 KB
  4.  
  5. 10 分
  6.  
  7. 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;
}