CF730I 题解
Solution
提供一种直接贪心的做法。
关于本题有很多种做法。事实上这题是 AT2672 的弱化版和简化版。
按照 \(a_i+b_j>a_j+b_i\) 排序后,显然在前一段选 \(a\) ,后一段选 \(b\) 。
贪心,用优先队列维护前缀选 \(a\) 的最大和后缀选 \(b\) 的最大。
对于选的集合,从上继承后再根据优先队列的弹出进行删除就可以了。
Code
/*
太弱了,被zsq大佬吊打了。zsq是一个十分牛逼的选手,手切黑题,AT和CF5000分,拥有IOI Au的水平,
可他谦虚谨慎,不慕名利,想要隐藏在众人之间,可是金子总会发光,他即将在NOIP 2022上AK。
*/
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("inline")
#include<bits/stdc++.h>
#define re register
#define fep(i,l,r) for(re int i=l;i<=r;++i)
#define For(i,u) for(re int i=head[u];i;i=e[i].nxt)
#define feb(i,r,l) for(re int i=r;i>=l;--i)
#define IOS ios::sync_with_stdio(false); cin.tie(0); cout.tie(0)
#define LL long long
#define max(x,y) (x>y?x:y)
#define min(x,y) (x<y?x:y)
//#define int long long
#define pr pair<int,int>
#define mpr make_pair
using namespace std;
const int N = 3e3+5;
int n,a,b,sum1[N],sum2[N],ans; bool vis1[N][N],vis2[N][N];
struct Node
{
int x,y,id;
inline bool operator <(const Node d1) const {return x+d1.y>y+d1.x;}
}p[N];
priority_queue<int,vector<int>,greater<int> > q;
inline int read() { int s=0,w=1; char ch=getchar(); while(!(ch<='9'&&ch>='0')) {if(ch=='-') w=-1; ch=getchar();} while(ch<='9'&&ch>='0') {s=(s<<1)+(s<<3)+ch-'0'; ch=getchar();} return s*w; }
inline void write(int x) { if(x>=10) write(x/10); putchar(x%10+'0'); }
inline void print(int x,char ch) { if(x<0) putchar('-'),x=~(x-1); write(x); putchar(ch);}
signed main()
{
n=read(),a=read(),b=read();
fep(i,1,n) p[i].x=read(),p[i].id=i;
fep(i,1,n) p[i].y=read();
sort(p+1,p+1+n);
fep(i,1,n)
{
q.push(p[i].x); sum1[i]=sum1[i-1]+p[i].x;
fep(j,1,n) vis1[i][j]=vis1[i-1][j]; vis1[i][p[i].id]=1;
if(q.size()>a)
{
sum1[i]-=q.top();
fep(j,1,n) if(vis1[i][p[j].id]&&q.top()==p[j].x)
{
vis1[i][p[j].id]=0; break;
}
q.pop();
}
}
while(!q.empty()) q.pop();
feb(i,n,1)
{
q.push(p[i].y); sum2[i]=sum2[i+1]+p[i].y;
fep(j,1,n) vis2[i][j]=vis2[i+1][j]; vis2[i][p[i].id]=1;
if(q.size()>b)
{
sum2[i]-=q.top();
fep(j,1,n) if(vis2[i][p[j].id]&&q.top()==p[j].y)
{
vis2[i][p[j].id]=0; break;
}
q.pop();
}
}
fep(i,a,n-b) ans=max(ans,sum1[i]+sum2[i+1]);
print(ans,'\n');
fep(i,a,n-b) if(ans==sum1[i]+sum2[i+1])
{
fep(j,1,n) if(vis1[i][j]) print(j,' '); puts("");
fep(j,1,n) if(vis2[i+1][j]) print(j,' '); puts("");
break;
}
return 0;
}

浙公网安备 33010602011771号