洛谷 P7542 MALI 题解

Posted Lotuses-robot

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了洛谷 P7542 MALI 题解相关的知识,希望对你有一定的参考价值。

又双叒叕了一篇题解...

题目简述

对于两个序列 A,序列 B,长度一致;

\\(n\\) 次操作,

每次操作都会向这两个序列增加数字。

在每次操作后,要求对每个序列中的每个数字配对,要让配对数之和最大值最小

Solution

贪心。

对每时每刻的序列排序,\\(a\\)从小到大\\(b\\)从大到小配对。

证明:

对于序列中最小的 \\(a_i\\),序列最大的\\(b_j\\)

若将 \\(a_i\\) 替换成 \\(a_k\\)\\(a_k>a_i\\) ,此时必有 \\(a_k+b_j>a_i+b_j\\),不必原计划更优;

若将 \\(b_j\\) 替换成 \\(b_k\\),且 \\(b_j<b_k\\),则必有 \\(a_z>a_i\\) 需要与 \\(b_j\\) 配对。所以必有更大值 \\(a_z+b_j>a_i+b_j\\),也不必原计划更优。

所以,每次选择最小和最大的配对可以得到最优解。

可惜直接排序时间复杂度不够。

时间复杂度为 \\(O(n^2\\log n)\\)\\(n\\leq 10^5\\),超时。

优化。

1、桶优化

发现 \\(1\\leq a_i,b_j\\leq 100\\),所以考虑直接桶排。

时间复杂度降为 \\(O(n^2)\\)

2、连续配对优化

发现当 \\(a_i,b_j\\) 出现多次时,会直接配出 \\(\\min(a_i,b_j)\\) 组一样的配对。

所以对于桶中 \\(a_i,b_j\\) ,每次配对时,对应减少 \\(\\min(a_i,b_j)\\) 即可。

最坏时间复杂度为 \\(O(100n)\\) ,不会超时。

AC Code

#include<bits/stdc++.h>
using namespace std;
int a[101],b[101];
int am[101],bm[101];

int main()
{
	int n,k,maxn=-414231;
	cin>>n;
	for(int i=1;i<=n;i++)
	{
		maxn=-414231;
		cin>>k,am[k]++;
		cin>>k,bm[k]++;  //优化1
		memcpy(a,am,sizeof(am));
		memcpy(b,bm,sizeof(bm)); //复制桶
		int l=1,r=100;
		while(r>=1&&l<=100)
		{
			while(!a[l]) l++;
			while(!b[r]) r--;
			if(r<1||l>100) break;
			maxn=max(maxn,l+r);
			minx=min(a[l],b[r]);
			a[l]-=minx;b[r]-=minx;  //优化2
		}
		cout<<maxn<<endl;
	}
	return 0;
}

qwq

我的洛谷题解

  • 2018.2.4 P1217【USACO1.5]回文质数 Prime Palindromes】
  • 2018.2.6  P1308 【统计单词数】

链接

持续更新中

以上是关于洛谷 P7542 MALI 题解的主要内容,如果未能解决你的问题,请参考以下文章

洛谷P1854 花店橱窗布置 分析+题解代码

洛谷P2832 行路难 分析+题解代码玄学最短路

洛谷 P2210 Haywire 题解报告

洛谷 P2194 HXY烧情侣Tarjan缩点 分析+题解代码

BZOJ2938 & 洛谷2444:[POI2000]病毒——题解

洛谷P1047校门外的树题解