打怪兽「掘金日新计划 · 2 月更文挑战」

111 阅读2分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 2 月更文挑战」的第 1 天,点击查看活动详情

打怪兽

题目描述

有 n 个怪兽(编号 1∼n),其中第 i 个怪兽的防御值为 ai。

你是一个魔法师,初始时拥有 m 点法力值。

当你的法力值大于 0 时,你可以对怪兽发动攻击,每一次攻击具体为:

  • 任意选择 1∼2 个怪兽,并消耗 x 点法力值(x 可以是一个不超过你当前法力值的任意正整数),对每个所选怪兽发动一次伤害为 x 的攻击。
  • 对于受到攻击的怪兽,如果其防御值小于或等于 x,则会被你消灭。否则,它将免疫此次攻击,不受任何影响。

请你确定最大的整数 k,满足:通过合理安排攻击,可以将第 1∼k 个怪兽全部消灭。

输入格式

第一行包含整数 n,m。

第二行包含 n 个整数 a1,a2,…,an。

输出格式

一个整数,表示最大的整数 k。

数据范围

前 33 个测试点满足 1≤n,m≤10。
所有测试点满足 1≤n≤1000,1≤m≤109,1≤ai≤m。

输入样例1:

5 7
2 3 5 4 1

输出样例1:

3

输入样例2:

10 10
9 1 1 1 1 1 1 1 1 1

输出样例2:

4

输入样例3:

5 10
3 1 4 2 4

输出样例3:

5

思路

这个题运用的是二分和排序贪心的算法解决的,思路比较容易想,但是有点点拐弯,考虑一下细节就好了/

代码

#include<bits/stdc++.h>
using namespace std;
#define int long long
#define IOS ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
const int N=2e5+10;
int a[N],b[N];
int n,m;

bool cmp(int a,int b){
    return a>b;
}

bool check(int k){
    memcpy(a,b,sizeof b);
    int f=m;
    sort(a+1,a+1+k,cmp);
    for(int i=1;i<k;i+=2)f-=a[i];
    if(k%2==1)f-=a[k];
    if(f<0)return false;
    return true;
}

signed main(){
    IOS;
    cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
    }
    memcpy(b,a,sizeof b);
    int l=1,r=n;
    while(l<r){
        int mid=(l+r+1)>>1;
        if(check(mid))l=mid;
        else r=mid-1;
    }
    cout<<l<<endl;
    return 0;
}