开启掘金成长之旅!这是我参与「掘金日新计划 · 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;
}