D - 3N Numbers
Time limit : 2sec / Memory limit : 256MB
Score : 500 points
Problem Statement
Let N be a positive integer.
There is a numerical sequence of length 3N, a=(a1,a2,…,a3N). Snuke is constructing a new sequence of length 2N, a', by removing exactly N elements from a without changing the order of the remaining elements. Here, the score of a' is defined as follows: (the sum of the elements in the first half of a')−(the sum of the elements in the second half of a').
Find the maximum possible score of a'.
Constraints
- 1≤N≤105
- ai is an integer.
- 1≤ai≤109
Partial Score
- In the test set worth 300 points, N≤1000.
Input
Input is given from Standard Input in the following format:
N a1 a2 … a3N
Output
Print the maximum possible score of a'.
把3N数组分为两部分,前部分选择N个最大的元素,后部分选择N个最小的元素,利用优先队列求一下和即可
#include<cstdio> #include<cstdlib> #include<cstring> #include<string> #include<algorithm> #include<iostream> #include<queue> #include<map> #include<cmath> #include<set> #include<stack> #define ll long long #define max(x,y) (x)>(y)?(x):(y) #define min(x,y) (x)>(y)?(y):(x) #define cls(name,x) memset(name,x,sizeof(name)) using namespace std; const int inf=1<<28; const int maxn=100010; const int maxm=110; const int maxk=100010; const int mod=1e9+7; const double pi=acos(-1.0); int n; int num[maxn*3]; ll maxleft[maxn],minright[maxn]; int main() { //freopen("in.txt","r",stdin); int a,b; while(~scanf("%d",&n)) { cls(maxleft,0); cls(minright,0); for(int i=0;i<n*3;i++) scanf("%d",&num[i]); priority_queue<int, vector<int>, greater<int> > Q1; priority_queue<int> Q2; for(int i=0;i<n;i++) { maxleft[0]+=num[i]; Q1.push(num[i]); minright[n+1]+=num[n*3-1-i]; Q2.push(num[n*3-1-i]); } for(int i=1;i<=n;i++) { Q1.push(num[n+i-1]); maxleft[i]=maxleft[i-1]+num[n+i-1]-Q1.top(); Q1.pop(); Q2.push(num[n*2-i]); minright[n+1-i]=minright[n+1-i+1]+num[n*2-i]-Q2.top(); Q2.pop(); } ll ans; for(int i=0;i<=n;i++) { if(i==0) ans=maxleft[i]-minright[i+1]; else ans=max(ans,maxleft[i]-minright[i+1]); } printf("%lld ",ans); } return 0; }