Lizard and basement (51Nod-1489)

Keywords: less

subject

Harry likes to play role-playing computer game lizard and basement. At this time, he is playing a magician. At the last level, he had to fight a line of archers. The only way he could kill them was a fireball spell. If Harry attacks the i-th archer with his fireball spell (they mark from left to right), the archer loses a health. At the same time, this spell makes the archer (if any) adjacent to the i-th Archer lose b(1 ≤ B < a ≤ 10) health points respectively.

Because the archers at both ends (i.e. the archers marked 1 and n) are far away from you, the fireball cannot directly attack them. But Harry can use his fireball to attack any other archer.

The health of each archer is known. When a archer's health is less than 0, the Archer will die. Ask for the minimum number of fireballs Harry needs to kill all enemies.

If the archer is dead, Harry can still throw his ball at the archer.

input

The first line contains three integers n, a, b (3 ≤ n ≤ 10; 1 ≤ B < a ≤ 10), the second line contains n integers - h1, h2,..., hn (1 ≤ hi ≤ 15), hi is the vitality of the i-th archer.

output

Output t in one line - the minimum number of fireballs required.

sample input

3 2 1
2 2 2

sample output

1

Thought: first, kill the first and the nth two people with residual damage, and then conduct dfs. It should be noted that the minimum value should be updated in the process of dfs. In addition, when the life of the archer is equal to 0, it is still regarded as survival, and only when it is less than 0, it will die

source program

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
const int MOD = 1E9+7;
const int N = 100+5;
const int dx[] = {-1,1,0,0};
const int dy[] = {0,0,-1,1};
using namespace std;
int h[N];
int n,a,b;
int cnt=INF;
void dfs(int pos,int ans){
    if(pos==n){
        if(cnt>ans)
            cnt=ans;
        return;
    }

    if(h[pos-1]<0)//Post-1 search backward after death
        dfs(pos+1,ans);

    int num1=0;//Number of times residual damage kills pos-1
    if(h[pos-1]>=0){
        num1=h[pos-1]/b+1;
        h[pos-1]-=num1*b;
        h[pos]-=num1*a;
        h[pos+1]-=num1*b;

        dfs(pos+1,ans+num1);

        h[pos-1]+=num1*b;
        h[pos]+=num1*a;
        h[pos+1]+=num1*b;

    }
    int num2=h[pos]/a+1;//Number of times to kill pos
    if(h[pos]>=0&&num1<num2){//The pos is not killed and num1 kills more times than num2
        for(int i=num1+1;i<=num2;i++){//Enumerations from num1 to num2
            h[pos-1]-=i*b;
            h[pos]-=i*a;
            h[pos+1]-=i*b;

            dfs(pos+1,ans+i);

            h[pos-1]+=i*b;
            h[pos]+=i*a;
            h[pos+1]+=i*b;
        }
    }
}

int main() {
    scanf("%d%d%d",&n,&a,&b);
    for(int i=1;i<=n;i++)
        scanf("%d",&h[i]);

    int res=0;
    int num;//Number of hits
    num=h[1]/b+1;//Residual injury killed the first one
    res+=num;

    h[1]-=num*b;//The first remaining blood volume after the second num
    h[2]-=num*a;//The second remaining blood volume after the second num
    h[3]-=num*b;//The third remaining blood volume after the second num

    if(h[n]>=0){//The last one didn't die
        num=h[n]/b+1;//n-1 times
        res+=num;
        h[n]-=num*b;//The remaining blood volume of the nth num after the nth num
        h[n-1]-=num*a;//The remaining blood volume of the nth-1st num
        h[n-2]-=num*b;//Remaining blood volume of the nth-2nd num after the nth num
    }


    dfs(2,0);
    if(cnt!=INF)
        res+=cnt;
    printf("%d\n",res);

    return 0;
}

 

Posted by vonnero on Sun, 24 Nov 2019 12:50:35 -0800