题解 AT2672 【[AGC018C] Coins】
看完题可以发现这是一个类似于[NOI2019]序列的题目,自然考虑反悔贪心。
vp赛时本蒟蒻本来先考虑先选
考虑因为
为方便,下文用
此时因为我们并不能改变选某种硬币的人数,所以我们能进行的变换只有类似于
然后一个人能进行的变换也只有
//W4P3R
#include<bits/stdc++.h>
#define inf 1e9
#define eps 1e-6
#define mp make_pair
#define pb push_back
#define re register ll
#define fr first
#define sd second
#define pa pair<ll,ll>
#define FOR(i,a,b) for(re i=a;i<=b;i++)
#define REP(i,a,b) for(re i=a;i>=b;i--)
#define MEM(a) memset(a,0,sizeof(a))
#define N 100010
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
inline ll read()
{
char ch=getchar();
ll s=0,w=1;
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9'){s=s*10+ch-'0';ch=getchar();}
return s*w;
}
inline ll lowbit(ll x){return x&(-x);}
ll n,X,Y,Z;
ll a[N],b[N],c[N];
ll vis[N],ans;
priority_queue<pa,vector<pa>,less<pa> >q1,q2,q3,q4,q5,q6;
inline void add(ll x)
{
q1.push(mp(b[x]-a[x],x));//x->y
q2.push(mp(c[x]-b[x],x));//y->z
q3.push(mp(a[x]-c[x],x));//z->x
q4.push(mp(c[x]-a[x],x));//x->z
q5.push(mp(b[x]-c[x],x));//z->y
q6.push(mp(a[x]-b[x],x));//y->x
}
int main()
{
//ios::sync_with_stdio(false);
//freopen(".in","r",stdin);
//freopen(".out","w",stdout);
X=read(),Y=read(),Z=read();n=X+Y+Z;
FOR(i,1,n)a[i]=read(),b[i]=read(),c[i]=read();
FOR(i,1,X)vis[i]=1,ans+=a[i];
FOR(i,X+1,X+Y)vis[i]=2,ans+=b[i];
FOR(i,X+Y+1,X+Y+Z)vis[i]=3,ans+=c[i];
FOR(i,1,n)add(i);
while(true)
{
while(!q1.empty()&&vis[q1.top().sd]!=1)q1.pop();
while(!q2.empty()&&vis[q2.top().sd]!=2)q2.pop();
while(!q3.empty()&&vis[q3.top().sd]!=3)q3.pop();
while(!q4.empty()&&vis[q4.top().sd]!=1)q4.pop();
while(!q5.empty()&&vis[q5.top().sd]!=3)q5.pop();
while(!q6.empty()&&vis[q6.top().sd]!=2)q6.pop();//反悔贪心在每次取值时弹出不合法状态往往更好写
ll v1=(q1.empty()?-inf:q1.top().fr),v2=(q2.empty()?-inf:q2.top().fr),v3=(q3.empty()?-inf:q3.top().fr);
ll v4=(q4.empty()?-inf:q4.top().fr),v5=(q5.empty()?-inf:q5.top().fr),v6=(q6.empty()?-inf:q6.top().fr);
ll maxn=0,t=0;
if(v1+v2+v3>maxn)maxn=v1+v2+v3,t=1;//情况1
if(v4+v5+v6>maxn)maxn=v4+v5+v6,t=2;//情况2
if(v1+v6>maxn)maxn=v1+v6,t=3;//情况3
if(v2+v5>maxn)maxn=v2+v5,t=4;//情况4
if(v3+v4>maxn)maxn=v3+v4,t=5;//情况5
if(!maxn)break;ans+=maxn;
if(t==1)
{
ll x=q1.top().sd,y=q2.top().sd,z=q3.top().sd;
vis[x]=2,vis[y]=3,vis[z]=1;
add(x);add(y);add(z);
}
if(t==2)
{
ll x=q4.top().sd,y=q5.top().sd,z=q6.top().sd;
vis[x]=3;vis[y]=2;vis[z]=1;
add(x);add(y);add(z);
}
if(t==3)
{
ll x=q1.top().sd,y=q6.top().sd;
vis[x]=2;vis[y]=1;
add(x);add(y);
}
if(t==4)
{
ll x=q2.top().sd,y=q5.top().sd;
vis[x]=3;vis[y]=2;
add(x);add(y);
}
if(t==5)
{
ll x=q3.top().sd,y=q4.top().sd;
vis[x]=1;vis[y]=3;
add(x);add(y);
}
}
cout<<ans<<'\n';
return 0;
}
//gl
如果你觉得这篇题解对你有帮助,那你可以点个赞支持我一下qwq。如果你对题解有任何问题/认为我的题解有任何问题,可以私信/在评论区发出来,当然如果你对我的题解有任何意见/建议也欢迎指出。我会尽我全力把我题解写到最好的qwq