题解:P10966 K-Anonymous Sequence
_zuoqingyuan · · 题解
“你只能做一个操作——减少序列中的一些数字”。
因为没看见这句话瞪这题瞪了两周。
前置:斜率优化 dp,模板题。
思路分析
怎么没有单调队列题解?
设
对于
对于
因为我们只能减小某个数字,而序列单调不下降,所以我们只能把
记
我们主要对后一种情况进行讨论,
把式子拆开,去掉
我们发现式子中只有一项同时包含
令
则式子可以化为
\text{Code}:
#include <iostream>
#include <cstring>
#include <cstdio>
#define int long long//防止爆 int
using namespace std;
const int N=5e5+10;
int n,k,a[N],s[N],l,r,q[N],dp[N];
inline int X(int x){return a[x+1];}
inline int Y(int x){return dp[x]-s[x]+x*a[x+1];}
void work(){
scanf("%lld %lld",&n,&k);k--;
for(int i=1;i<=n;i++)scanf("%lld",a+i),s[i]=a[i]+s[i-1];
q[l=r=1]=0;dp[0]=0;//初始化
for(int i=1,j;i<=n;i++){
if(i<=k){dp[i]=0x3f3f3f3f;continue;}
while(l<r&&(Y(q[l+1])-Y(q[l]))<=i*(X(q[l+1])-X(q[l])))l++;//防止精度误差
dp[i]=dp[j=q[l]]+s[i]-s[j]-(i-j)*a[j+1];
while(l<r&&(Y(q[r])-Y(q[r-1]))*(X(i-k)-X(q[r]))>=(Y(i-k)-Y(q[r]))*(X(q[r])-X(q[r-1])))r--;//防止精度误差
q[++r]=i-k;//决策入队
}
printf("%lld\n",dp[n]);
return;
}
void clear(){//清空
memset(q,0,sizeof(q));
memset(dp,0,sizeof(dp));
l=r=0;
return;
}
signed main(){
int T=0;
cin>>T;
while(T--){
work();
clear();
}
return 0;
}
如有错误,请指出。