区赛题目详解(贪心的灵活运用)

1.题目描述 

帝丹学校在举办两人三足接力的比赛,以班级为单位进行比赛,由于是接力比赛,只有当前一组跑完的时候,才会轮到下一组,且每组队伍必须由一位男生和一位女生组成。
请注意,这是一个双人的游戏,考察的是团队配合能力,需要两人的速度保持一致的时候才能跑起来,要不然,速度不匹配非常容易磕到,毕竟是男女生,磕到一起就不好了。
为了取得比赛的胜利,小兰的班级派出 n 名男生和女生参加比赛,由于每位选手的速度可能不一样,需要小兰来帮助不是很聪明的学弟学姐们组建出一个队伍出来。
这种问题对小兰来说根本不算什么,那么让你来做,求出班级最强队伍的总速度以及最弱队伍的总速度,班级队伍的总速度为所有组队速度之和。
输入
输入三行;
第一行,输入 n,表示共 n 名男生和女生。
第二行,输入 n 个数据, 表示男生的速度 a i 。
第三行,输入 n 个数据,表示女生的速度 b i 。
输出
输出两行;
第一行,输出班级最强的队伍的总速度。
第二行,输出班级最弱的队伍的总速度。
样例输入 Copy
3
5 1 4
6 3 3
样例输出 Copy
9
7
提示
【数据范围】
对于 30% 的数据 1 < n ≤ 10^3 , 1 ≤ ai ,bi ≤ 10^6 ;
对于 50% 的数据 1 < n ≤ 10^3 , 1 ≤ ai ,bi ≤ 10^9 ;
对于 100% 的数据 1 < n ≤ 10^6 , 1 ≤ ai ,bi ≤ 10^9 ;

 2.题目分析

拿到一道题先要分析它的样例。但这道题难就难在对题目的理解上。不仿我们先来琢磨琢磨题目是什么意思。

这道题将它变换一下说法就是:有N个男生和N个女生,每一个男生和一个女生一组(一组就是一组,一个人不能同时待在两个组里,每组的速度就是那个跑得最慢的人的速度(待会我会解释为什么),班级速度就是所有组的速度之和。求出最大的班级速度是多少,最小又是多少?

在上一段中我标红的部分我来解释下为什么:题目中说过“需要两人速度一致才能跑起来”,也就是说,在保证这一组的速度是最优解的情况下,我们要的不是那个最大的人的速度,而是最小的(比如这一组是 6 11,那么速度就是6而非11),因为若要速度为最大的人的,那么另一个人就跟不上了!!!

3.代码

#include<bits/stdc++.h>
#define MX 1000000
using namespace std; 
int main()
{
	long long int n,i,j,ma = 0,mn = 0;
	long long int a[MX + 10],b[MX + 10];
	cin >> n;
	for (i = 1;i <= n;i++)
	{
		cin >> a[i];
	}
	for (i = 1;i <= n;i++)
	{
		cin >> b[i]; 
	}
	sort(a + 1,a + n + 1);
	sort(b + 1,b + n + 1);
    //判断最强队伍部分
	for (i = 1;i <= n;i++)
	{
		ma += min(a[i],b[i]);
	}
    //判断最弱队伍部分
	for (i = 1;i <= n;i++)
	{
		mn += min(a[i],b[n - i + 1]);
	} 
	cout << ma << endl; 
	cout << mn << endl;
	return 0;
}

4.解题思路

实际上,在分析完题目之后,这道题就很简单了。很明显,这道题就是一个贪心——我们可以通过求每一组的最优解来获得全局最优解。那么贪心的策略是什么呢?

让我们先看最强队伍的:

既然已经分析出是贪心,我们要做到的就是想法子让每一组的的速度最大,即让男生里面的最大值(在从小到大排序之后就是a[n])和女生的最大值为一组(即b[n]),为什么要这样分配呢?因为我们要让每组速度最大,也就是这一组的最小值为最大,肯定就是让男生女生的最大值在一组中,至于到底是b[n] > a[n]还是a[n] > b[n]这件事并非我们关心的(无所谓),我们关心的仅仅是一组中的最大值而已。a[n]和b[n]为一组后,a[n - 1]和b[n - 1]为一组,为什么呢?因为我们除去a[n]和b[n]剩下的男女生最大值就是a[n - 1]和b[n - 1]了。剩下的以此类推……最终到a[1]和b[1]为一组,得到的每组中的最小值的累加和就是最强队伍的最优解。

//实际上判断最强队伍还可以这么写
while(n--)
{
   ma += min(a[n],b[n]);
}

那么最弱队伍的呢?

最弱队伍与最强队伍正好相反,我们在最强中要让每组速度最大,在最弱中就要让每组速度尽可能小。也就是男生的最大值与女生的最小值为一组(排序后即a[n]和b[1]),男生的第二大值和女生第二小值为一组(a[n - 1]和b[2]),与最强队伍是换汤不换药。得到每一组最小值的累加和就是最弱队伍的最优解。

//与上面类似,判断最弱队伍还可以这么写
int m = 1;
while(n--)
{
   mn += min(a[n],b[m]);
   m++;
}

5.注意事项

实际上,我在“4解题思路”最强队伍中用了两个名词,一个是“男生女生最大值”还有一个是“每一组的最小值”。有人会问:最强队伍不是求最大值吗?怎么要求最小值?实际上这种人确实是还没有理解题目。“最小值”指的是“每一组中”的最小值,比如样例这组数据每一组的最小值就是“5 1 3”(没排序的下标);而最大值指的是“全局”的最大值,这是最强队伍的最优解。这两个量要搞清楚,否则就没法做题。

6.

   

-加上这个才算完美-

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值