题意: A和B轮流取数, 已知A可以随意选取, B会按着给出的序列依次取, 问A在最优的情况下, 取得的数的总和比B的大多少.
思路: 如果我们按照题意的思路想, 发现A选的数并不容易确定. 但是我们可以发现, A随意选且最优 相当于 A也按照B的那个序列取,只不过当B选的时候, A可以将之前自己选的最小值换给B.
换句话说, B每次取到的数 都是比 当前所有A取到的数 都小的数. 同时, 因为当前A取了的数, 一定是B可以取的数(在原序列中, 在当前数之前的数), 所以换给B是没有问题的. 这个过程就相当于A在之前就提前将这个数抠走了.
代码:
#include<bits/stdc++.h>
using namespace std;
#define fuck(x) cout<<#x<<" "<<x<<endl;
const int inf=1e9+7;
int a[105],b[105];
priority_queue <int,vector<int>,greater<int> > qq;
int main() {
int n;
cin>>n;
for(int i=1; i<=n; i++)
scanf("%d",&(a[i]));
for(int i=1; i<=n; i++) {
scanf("%d",&(b[i]));
b[i]=a[b[i]];
}
int x=0,y=0;
queue<int>q;
for(int i=1; i<=n; i++) {
q.push(b[i]);
}
int minn=inf;
while(!q.empty()) {
int aa=q.front();
q.pop();
int bb=q.front();
q.pop();
if(aa<bb)
swap(aa,bb);
// fuck(aa);
// fuck(bb);
if(!qq.empty()&&bb>qq.top()) {
x-=qq.top(),y+=qq.top(),x+=aa,x+=bb;
qq.pop();
qq.push(aa);
qq.push(bb);
} else {
x+=aa,y+=bb;
qq.push(aa);
}
// fuck(x);
// fuck(y);
}
printf("%d\n",x-y);
return 0;
}