POJ 3465 [battle] 优先级队列+反悔贪心

题意

你是强大的英雄朱仁功。 经过一系列具有挑战性的任务之后,您终于要面对最终的老板-一条叫做黑龙的黑龙。 由于他的压倒性优势,您必须仔细计划自己的行动。
战斗一开始你有H1生命值(HP),而黑龙有H2。 每次执行动作,黑龙都会攻击您,并在第i轮造成艾点伤害。 您有三种动作。

  • 攻击。 您攻击黑龙,并造成x点伤害。
  • 防守。 您专注于避免受到黑龙的攻击。 此举使黑龙的这一轮攻击无效。
  • 愈合。 您可以自愈,为自己增加生命值。 您的HP没有上限。
    如果任何人的HP下降到0或等于0以下,他就会死亡。 如果您无法在N轮之内杀死巨龙,您也会死亡。 因此,您需要知道杀死黑龙需要多少回合。 如果您无法杀死他,则必须计算出对黑龙可能造成的最大伤害。

思路

贪心+反悔,使用优先级队列,有点前缀和的味道,每次尽量选择硬怼策略,如果大龙没死,自己先挂了,去优先级队列中寻找伤害最大的那个,进行生命值“反悔补充”,同时需要注意的是,反悔的同时,黑龙的生命值也要进行反悔式的增加。
结合代码食用比较好

代码

void C(){
    int n,x,y,h1,h2;
    scanf("%d %d %d %d %d",&n,&x,&y,&h1,&h2);
    //cin>>n>>x>>y>>h1>>h2;
    vector<ll> a(n,0);
    for(int i=0;i<n;i++)scanf("%lld",&a[i]);
    priority_queue<ii,vector<ii>,less<ii> > que;
    bool ok=false;
    int round=-1;
    ll ma=0;
    ll boss=h2,kight=h1;
    for(ll i=0;i<n;i++){
        boss-=x;
        ma=max(ma,h2-boss);
        if(boss<=0){
            ok=true;
            round=i+1;
            break;
        }
        que.push({a[i],i});//保存每次伤害
        kight-=a[i];
        if(kight<=0){
            while(kight<=0&&!que.empty()){//进行反悔操作,取伤害最大的进行反悔
                kight+=max((ll)y,a[que.top().second]);
                boss+=x;
                que.pop();
            }
            if(kight<=0){
                break;
            }
        }
    }
    if(ok){
        printf("Win\n%d\n",round);
    }
    else {
        printf("Lose\n%lld\n",ma);
    }
}

你可能感兴趣的:(POJ 3465 [battle] 优先级队列+反悔贪心)