51nod1493 数据相关

18 篇文章 0 订阅
题目来源:  CodeForces
基准时间限制:1 秒 空间限制:131072 KB 分值: 80  难度:5级算法题
 收藏
 关注

现在我们要关联两张表,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));  
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值