题意:从1~m中选一个数插入到a中,然后把这n+1个数,分成(n+1)/2组,每一组权值和最小。
思路:先将a数组排个序,然后枚举要放的数,二分找到大于等于b的位置,如果该位置是奇数就选择该位置,如果是偶数,–pos,然后加上这个点的权值差加上不算该点的前缀和 加 后缀和。更新一下答案就可以了。简单的贪心都做不出,凭什么拿铜牌啊。。
代码:
#include<bits/stdc++.h>
using namespace std;
const int N=200010;
#define int long long
int n,m;
typedef long long ll;
ll a[N];
ll b[N];
ll sum[N];
ll res;
ll ssum[N];
signed main()
{
cin>>n>>m;
for(int i=1;i<=n;i++)
cin>>a[i];
for(int i=1;i<=m;i++)
cin>>b[i];
sort(a+1,a+1+n);
for(int i=3;i<=n;i+=2)
sum[i]=sum[i-2]+a[i-1]-a[i-2];
for(int i=n-2;i>=1;i-=2)
ssum[i]=ssum[i+2]+a[i+2]-a[i+1];
ll res=1e18;
for(int i=1;i<=m;i++)
{
int pos=lower_bound(a+1,a+1+n,b[i])-a;
if(pos%2==0)
pos--;
res=min(res,ssum[pos]+sum[pos]+abs(b[i]-a[pos]));
}
cout<<res<<endl;
}
/* hack数据: 5 4 10739 32395 18445 21142 1786 4675 18873 24405 21179 */