P7542 MALI

  1. 1. Solution

又双叒叕了一篇题解…

题目简述

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

次操作,

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

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

Solution

贪心。

对每时每刻的序列排序,从小到大从大到小配对。

证明:

对于序列中最小的 ,序列最大的

若将 替换成 ,此时必有 ,不必原计划更优;

若将 替换成 ,且 ,则必有 需要与 配对。所以必有更大值 ,也不必原计划更优。

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

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

时间复杂度为 ,超时。

优化。

1、桶优化

发现 ,所以考虑直接桶排。

时间复杂度降为

2、连续配对优化

发现当 出现多次时,会直接配出 组一样的配对。

所以对于桶中 ,每次配对时,对应减少 即可。

最坏时间复杂度为 ,不会超时。

AC Code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#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