51Nod1489 蜥蜴和地下室(dfs)

//1489蜥蜴和地下室
/*先处理第一个弓箭手和最后一个,
中间的弓箭手x有两种被消灭的方法,
假如打死第x-1个弓箭手后,x没有死。
那么第一种是通过直接被打死,
第二种是通过攻击x+1的弓箭手*/
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 30
#define inf 0x3f3f3f3f
typedef long long ll;
int n,a,b,A[maxn],tmp=inf;
ll ans=0;
void dfs(int x,int num) //x是当前弓箭手的序号,num是当前释放的火焰的数目
{
   // tmp=0;
    if(x==n-1){
        tmp=min(num,tmp);
        return ;
    } 
    int t=0; 
    /*每一次向后搜索都要保证X-1为负数 
    前面一个还没死,只能通过打后面一个附带杀死x-1*/ 
    if(A[x-1]<0) dfs(x+1,num);
    if(A[x-1]>=0){
        t=A[x-1]/b+1;
        A[x-1]-=t*b;
        A[x]-=t*a;
        A[x+1]-=b*t;
        dfs(x+1,num+t);
        A[x-1]+=t*b;
        A[x]+=t*a;
        A[x+1]+=b*t;
    }
    //假如打爆x-1x还活着,那么打x次数一定还要大于t(杀死前面一个) 
    int time=A[x]/a+1;
    if(time>t&&A[x]>=0){
        for(int i=t+1;i<=time;i++){
            A[x-1]-=i*b;
            A[x]-=i*a;
            A[x+1]-=i*b;
            dfs(x+1,num+i);
            A[x-1]+=i*b;
            A[x]+=i*a;
            A[x+1]+=i*b;
        }
    }
return ; 
}
int main(){
    cin>>n>>a>>b;
    for(int i=0;i<n;i++) cin>>A[i];
    //先处理两端的
    int t1=A[0]/b+1;    //小于0才可以
    A[0]-=t1*b;
    A[1]-=t1*a;
    A[2]-=t1*b;
    ans+=t1;
    if(A[n-1]>=0){
        int t2=A[n-1]/b+1;
        A[n-1]-=t2*b;
        A[n-2]-=t2*a;
        A[n-3]-=t2*b;
        ans+=t2;
    }
    //处理中间的
    dfs(1,0);
    if(tmp!=inf){
        ans+=tmp;
    }
    cout<<ans<<endl;
    return 0;
}

WA了,用贪心写的,后来想想这种写法并不对,应该是一道深搜题。

//1489蜥蜴和地下室
#include<iostream>
#include<algorithm>
using namespace std;
#define maxn 30
typedef long long ll;
int n,a,b;
ll ans=0;
typedef struct Node{
    int l,r,value;
}node;
//判断是不是整数
bool isInterger(double x){
    if(x==int(x)) return true;
    return false;
}
bool cmp(node a,node b){
    return a.value>b.value;
}

node A[maxn];
int main(){
    cin>>n>>a>>b;
    for(int i=0;i<n;i++){
        cin>>A[i].value;
        if(i!=0&&i!=n-1){
            A[i].l=i-1;
            A[i].r=i+1;
        }
    }
    //solve
    sort(A+1,A+n-2,cmp);
    for(int i=1;i<=n-2;i++){
        while(A[i].value>=0){
            A[i].value-=a;
            A[i-1].value-=b;
            A[i+1].value-=b;
            ans++;
           // cout<<"1  "<<ans<<endl;
        }
    }
    //A[0] and A[n-1]
    if(n>3){
        while(A[0].value>=0){
            A[0].value-=b;
            ans++;
        }
        while(A[n-1].value>=0){
            A[n-1].value-=b;
            ans++;
        }
    }
    else{
        int tmp=max(A[0].value,A[1].value);
        while(tmp>=0){
            tmp-=a;
            ans++;
          //  cout<<"2  "<<ans<<endl;
        }
    }

    //print
    cout<<ans<<endl;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值