专栏文章
AT_abc400_g [ABC400G] Patisserie ABC 3 题解
AT_abc400_g题解参与者 2已保存评论 1
文章操作
快速查看文章及其快照的属性,并进行相关操作。
- 当前评论
- 1 条
- 当前快照
- 1 份
- 快照标识符
- @mipoyz2g
- 此快照首次捕获于
- 2025/12/03 15:34 3 个月前
- 此快照最后确认于
- 2025/12/03 15:34 3 个月前
调的有点久。
如果不考虑 的限制,那么有一个显然的 DP:先把 的贡献拆掉,转化成选一些数两两配对,计算他们 的贡献;再选另外一些数配对,计算他们 的贡献;对 同理。
又由于他们可以任意配对,所以限制就可以直接写成:
从序列中选出三组数,其中每一组的数量都是偶数。答案是第一组的 之和加上第二组的 之和加上第三组的 之和。
这样是对的,因为错解一定是不优的。
DP 的时候直接多记一维状态 表示三组数个数的奇偶性即可。单次时间复杂度 。
现在加上 的限制。我们发现选 组的答案关于 是凸的(理解一下就是一定会先选出贡献大的数对,斜率是不增的)。直接上 wqs 二分就行。
写的时候注意一下二分的是 到 之间的斜率,要进行一些乘除 的处理,具体看代码吧。
CPP#include<bits/stdc++.h>
inline void rd(){}
template<typename T,typename ...U>
inline void rd(T &x,U &...args){
int ch=getchar();
T f=1;x=0;
while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
while(ch>='0'&&ch<='9')x=(x<<1)+(x<<3)+(ch^48),ch=getchar();
x*=f;rd(args...);
}
const int N=1e5+5;
typedef long long ll;
const ll INF=1e18;
int T,n,k,v[N][3];
std::pair<ll,int> dp[N][8];
inline std::pair<ll,int> Solve(int x){
for(int i=0;i<8;i++)dp[0][i]={-INF,0};
dp[0][0]={0,0};
for(int i=1;i<=n;i++){
for(int j=0;j<8;j++){
dp[i][j]=dp[i-1][j];
for(int k=0;k<3;k++){
auto tmp=std::make_pair(dp[i-1][j^(1<<k)].first+2*v[i][k]-x,dp[i-1][j^(1<<k)].second+1);
dp[i][j]=std::max(dp[i][j],tmp);
}
}
}return dp[n][0];
}
inline void Solve(){
rd(n,k);
for(int i=1;i<=n;i++)rd(v[i][0],v[i][1],v[i][2]);
int L=0,R=2e9;
while(L<=R){
int mid=(0ll+L+R)>>1;
Solve(mid);
if(dp[n][0].second>=2*k)L=mid+1;
else R=mid-1;
}
Solve(R);
printf("%lld\n",dp[n][0].first/2+1ll*k*R);
}
signed main(){
rd(T);
while(T--)Solve();
return 0;
}
相关推荐
评论
共 1 条评论,欢迎与作者交流。
正在加载评论...