题解:AT_utpc2021_e Bounding Box
首先如果我们不考虑那些坐标的贡献,那就是一个十分显然的贪心。
我们首先按照价值排序,然后可以直接选择前
考虑后面的选择,我们设
我们处理出集合的贡献之后,枚举
对于当前枚举到的
最后答案就是前面选择的和后面 dp 选择的总和统计即可。
#include <bits/stdc++.h>
#define int long long
#define rep(i,l,r) for(int i=l;i<=r;++i)
#define per(i,r,l) for(int i=r;i>=l;--i)
using namespace std;
const int N=2e5+10;
int val[N][17];
int f[N][17];
int n,k;
int sum;
struct E{
int x,y,c;
bool operator<(E a)const{
return c>a.c;
}
}a[N];
signed main() {
cin>>n>>k;
rep(i,1,n){
cin>>a[i].x>>a[i].y>>a[i].c;
}
sort(a+1,a+n+1);
if(k>4){
rep(i,1,k-4){
sum+=a[i].c;
a[i].c=0;
}
}
rep(i,1,n){
rep(j,0,15){
int &v=val[i][j];
v=a[i].c;
if(j&1) v+=a[i].x;
if(j&2) v-=a[i].x;
if(j&4) v+=a[i].y;
if(j&8) v-=a[i].y;
}
}
memset(f,-0x3f,sizeof f);
f[0][0]=0;
rep(i,1,n){
per(j,min({i,k,4ll}),0){
per(s,15,0){
for(int t=s;;t=((t-1)&s)){
int &v=f[j][s];
if(!a[i].c) v=max(v,f[j][t]+val[i][s^t]);
else if(j) v=max(v,f[j-1][t]+val[i][s^t]);
if(!t) break;
}
}
}
}
cout<<sum+f[min(4ll,k)][15]<<'\n';
return 0;
}