P6155 修改
首先呢,可以知道,每个数都要去它右边第一个空位置
然后对于\(a_i,a_j\),假如\(b_i,b_j\)是空位的话,那么无论\(a_i,a_j\)谁去哪里,总距离不变
那么显然让每一个数去它右边的第一空是最有的(拉开距离差距)
然后按照距离分配b
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<stack>
#define int unsigned long long
using namespace std;
int n;
int a[1000006];
int b[1000006];
int p;
stack <int> s;
int cnt;
int ne[1000006];
bool cmp(int x,int y){
return x>y;
}
signed main(){
scanf("%d",&n);
for(int i=1;i<=n;++i){
scanf("%d",&a[i]);
}
for(int i=1;i<=n;++i){
scanf("%d",&b[i]);
}
a[++n]=1000000009;
sort(a+1,a+n+1);
sort(b+1,b+n);
for(int i=2;i<=n;++i){
if(a[i]==a[i-1]){
s.push(i);
}else{
int len=a[i]-a[i-1]-1;
int pp=1;
while(!s.empty()&&pp<=len){
ne[++cnt]=a[i-1]+pp-a[s.top()];
s.pop();
pp++;
}
}
}
int ans=0;
sort(ne+1,ne+cnt+1,cmp);
for(int i=1;i<=cnt;++i){
// cout<<ne[i]<<endl;
ans+=b[i]*ne[i];
}
cout<<ans;
return 0;
}