ural 1522

首先推一下柿子,尝试 exchange argument,发现 \(A,B,C\) 分别为 \(a_x+b_x+c_x\)\(\max(a_x+b_x+c_x,\max(a_x+b_x,a_x+a_y)+b_y)+c_y\)

如果 \(\max(b_i)\le \min(a_i)\)

\(\max(a_x+b_x+c_x,a_x+a_y+b_y)+c_y\)\(=\max(c_x+b_x,a_y+b_y)+a_x+c_y\)

如果 \(\max(b_i)\le \min(c_i)\)

\(\max(a_x+b_x+c_x,a_x+a_y+b_y)+c_y\)\(=\max(c_x+b_x,a_y+b_y)+a_x+c_y\)

对于 \(C\) 而言,那么 \(x\)\(y\) 前也就是 \(\max(c_x+b_x,a_y+b_y)+a_x-c_x<\max(c_y+b_y,a_x+b_x)+a_y-c_y\)

下面是胡扯。如果有严谨证明偏序的请踢我。

我们显然想要 \(\max\) 在同一边。那么如果存在 \(c_x+b_x<a_y+b_y\) 而且 \(c_y+b_y>a_x+b_x\) 是不好的。那么如果按照 \(a+b\) 从小到大排序,不成立当且仅当 \(a<c\)

反过来类似。

因此可以排序。在保证 \(C\) 小的情况下注意要保证 \(B\) 更小。

#include <bits/stdc++.h>

using namespace std;

using ll = long long;

const int N = 1e5+5;

int n;

struct node {
	ll a,b,c,id;
	bool operator < (const node &x) const {
		ll u=max(b+c,x.a+x.b)+a+x.c;
		ll v=max(x.b+x.c,a+b)+x.a+c;
		return u!=v?u<v:a<x.a;
	}
} p[N];

int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin>>n;
	for (int i=1; i<=n; i++){
		cin>>p[i].a>>p[i].b>>p[i].c;
		p[i].id=i;
	}
	sort(p+1,p+1+n);
	ll A=0,B=0,C=0;
	for (int i=1; i<=n; i++){
		A+=p[i].a;
		B=max(A,B)+p[i].b;
		C=max(B,C)+p[i].c;
	}
	cout<<C<<"\n";
	for (int i=1; i<=n; i++) cout<<p[i].id<<" ";
	cout<<"\n";
	return 0;
}
posted @ 2024-11-30 20:02  SFlyer  阅读(25)  评论(0)    收藏  举报