首先推一下柿子,嘗試 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;
}