[ABC218H] Red and Blue Lamps 题解
EastPorridge · · 题解
离 2023 NOI 春季测试 还有
感觉一下
寄了,无法上数据结构优化转移,所以它必须带点性质,
恰好选
套路抛弃选
我看官方题解给的是写成区间 dp 的形式,通过凸性做分治,也挺好的。
Code.
#include<bits/stdc++.h>
#define ll long long
int read()
{
int x=0; bool f=0; char ch=getchar();
while(ch < '0' || ch > '9') f|=(ch == '-'),ch=getchar();
while(ch >= '0' && ch <= '9') x=x*10+(ch^48),ch=getchar();
return f ? -x : x;
}
using namespace std;
const int N=2e5+10;
int a[N],n,k,cnt[2][N]; ll f[2][N];
bool check(ll mid)
{
f[1][1]=mid; cnt[1][1]=1;
for(int i=2;i<=n;i++)
{
(f[0][i-1] < f[1][i-1] + a[i]) ? (f[0][i]=f[1][i-1]+a[i],cnt[0][i]=cnt[1][i-1]) : (f[0][i]=f[0][i-1],cnt[0][i]=cnt[0][i-1]);
(f[0][i-1] + a[i] < f[1][i-1]) ? (f[1][i]=mid+f[1][i-1],cnt[1][i]=cnt[1][i-1]+1) : (f[1][i]=mid+f[0][i-1]+a[i],cnt[1][i]=cnt[0][i-1]+1);
}
return (f[1][n] > f[0][n]) ? (cnt[1][n] <= k) : (cnt[0][n] <= k);
}
int main()
{
n=read(); k=read(); for(int i=2;i<=n;i++) a[i]=read();
ll l=-2e9,r=2e9,res=0;
while(l <= r)
{
ll mid = (l + r) >> 1ll;
if(check(mid)) l=mid+1,res=max(f[1][n],f[0][n])-k*mid;
else r=mid-1;
}
printf("%lld\n",res);
return 0;
}