现在我们要关联两张表,A和B。每张表中有一些数据,这些数据被分成好多块。表A中有m个块。第i块有ai条数据。表B中有n个块,第i块有bi条数据。
每一次操作可以将一条数据从一个块复杂到另外一个块。最后的目标是对于A中某一条数据和B中某一条数据他们会同时会出现在至少一个块中。问最少的操作次数。
样例解释:可以将所有的数据都复制到B中的第二个块中。这样答案就是2+6+3=11。
Input
单组测试数据。 第一行有两个整数 m 和 n (1 ≤ m, n ≤ 10^5)。 第二行有m个整数ai (1 ≤ ai ≤ 10^9),表示A里面每一个块的数据条数。 第三行有n个整数 bi (1 ≤ bi ≤ 10^9),表示B里面每一个块的数据条数。
Output
输出最少的操作次数。
Input示例
2 2 2 6 3 100
Output示例
11
题解:贪心。策略:将a数组升序排列,b数组升序排列,求出a的和ma,b的和mb。一共就两种情况,要么将A合并到B,要要么将B合并到A,取两者的小值即可。如果是将B合并到A中,我们就将a数组遍历一下,a[i]>=mb就保留a[i],将mb合并到a[i]中,花费为mb,否则,将a[i]合并到A的其他组中,花费为a[i],注意一点如果是a的最后一项必须保留,哪怕是比mb小,也要保留下来,将mb合并进来,因为是将B合并到A,A中应该至少保留一项。
想了一下这个题解,假设我们是把B合并到A中,那么对于每个a,我们都有两种选择:要么把mb全都赋给a数组,要么把a数组赋给另一个a数组,那么代价为a[i],所以我们取两者中的min即可。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,m,i;
long long ma,mb,sum,ans,a[100001],b[100001];
int main(){
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++){
scanf("%lld",&a[i]);
ma+=a[i];
}
for(i=1;i<=m;i++){
scanf("%lld",&b[i]);
mb+=b[i];
}
sort(a+1,a+n+1);
sort(b+1,b+m+1);
for(i=1;i<=n;i++)
if(a[i]>=mb||n==i)ans+=mb;
else ans+=a[i];
for(i=1;i<=m;i++)
if(b[i]>=ma||m==i)sum+=ma;
else sum+=b[i];
printf("%lld",min(ans,sum));
}