牛牛的战役

牛牛的战役
链接:https://ac.nowcoder.com/acm/problem/21613
来源:牛客网

牛牛逐渐成长,战斗力也渐渐增加,并可以指挥若干个oier协同作战
给你一个数组a表示我方每个人的战斗力
再给你一个数组b

再给你一个数组c

c[i]表示敌方b[i]战斗力的人有c[i]个

每个oier每次可以选择一名敌方人员进行战斗,如果战斗力大于等于敌方人员,就可以战胜,经验值+1

最开始的时候每个人的经验值都是0

现在牛牛想要打败所有敌方人员,也就是说每个敌方人员都要被一个oier所打败

但是牛牛想要最小化最大的经验值

如果不能打败所有的敌方人员,输出-1

否则输出最小化最大的经验值
输入
3
2 3 5
3
1 3 4
2 9 4
输出
7

可以二分可以贪心的一道题。
因为当初是通过标签贪心搜索到的这道题目,所以自己没有去写二分去尝试了贪心,同学去写了二分。
先说说二分,二分可以解决一类题型,就是最大值最小,或者最小值最大。这道题之中就有这一点,题目要求是最小化最大的经验值。这一点就契合了二分的条件,每次去二分答案,也就是去二分最后的经验最大值,然后去计算。如果计算出来的经验最大值小于当前尝试的二分结果,那么就可以往小区间(l=mid-1)方向,否则就往大区间方向。

我们再讲讲贪心,想要最大值最小,那么最优的策略就是平均分,如果一个oier打败的敌人超过了平均值,那么就可以请能力值大于这个oier的其它oier来帮忙,从而进行分担,达到减少最大值的目的。这里我们使用top变量来表示这个平均值。为了方便实现,需要对oier的能力值和敌人的能力值进行排序。然后从能力最小的oier开始贪心,每次都先计算一个平均值。如果当前oier能击败敌人,并且经验不大于平均值,那么就让这个oier继续去击败下一个强度的敌人(如果这个oier可以的话,也就是oier能力值大于下一个敌人,否则就使用下一个oier)。
但是这个强度的敌人全部由这个oier来击败后,大于了平均值,那么我们就需要操作一下,只让这个oier击败敌人后到达平均值就停止,不能继续。然后换下一个oier继续上述的操作,每次都计算一下最大值。最后输出答案。

#include<cstdio>
#include<iostream>
#include<cmath>
#include<vector>
#include<stack>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;
typedef long long ll;
ll n,m,sum=0,maxxa=0,maxxb=0;
ll a[56];
struct node {
	ll val;
	ll cou;
};
struct node b[56];
bool cmp(struct node x,struct node y){
	return x.val<y.val;
}
int main(){
	#ifdef LOCAL
	freopen(".\\a.in", "r", stdin);
	#endif
	scanf("%lld",&n);
	for(int i=1;i<=n;i++){
		scanf("%lld",&a[i]);
		maxxa=max(a[i],maxxa);
	}
	scanf("%lld",&m);
	for(int i=1;i<=m;i++){
		scanf("%lld",&b[i].val);
		maxxb=max(maxxb,b[i].val);
	}
	for(int i=1;i<=m;i++){
		scanf("%lld",&b[i].cou);
		sum+=b[i].cou;
	}
	if(maxxa<maxxb){//无法击败所有敌人
		printf("-1\n");
		return 0;
	}
	sort(a+1,a+n+1);
	sort(b+1,b+m+1,cmp);
	ll ans=0;
	int nowb=1;
	for(int i=1;i<=n;i++){
		ll top=sum/(n-i+1);//平均值
		ll tmp=0;//当前oier已经击败的敌人数量
		while(a[i]>=b[nowb].val&&nowb<=m){//如果当前oier可以击败敌人
			if(tmp+b[nowb].cou>top){//击败敌人后会超过平均值
				b[nowb].cou=b[nowb].cou-(top-tmp);
				sum-=(top-tmp);
				tmp=top;
				break;
			}
			else {//不会超过平均值,就将所有敌人都击败
				tmp+=b[nowb].cou;
				sum-=b[nowb].cou;
				b[nowb].cou=0;
				nowb++;
			}
		}
		ans=max(ans,tmp);
	}
	printf("%lld\n",ans);
	return 0;
}
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下 4载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合;、下载 4使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值