CF833B 题解
原题传送门#
题意:将一个长度为
划分问题,可以考虑
暴力转移的时间复杂度为
首先此题的要点显然就在于题目中价值的定义。显然它满足区间包含单调性,然后再简单的手玩一下可以发现它也满足四边形不等式。(如果我没出错的话应该是四边形恒等式,但是反正不影响就是了)
既然
那就直接二分呗,用分治就好了,至于为什么,我觉得就是个经典
分治的过程比较板,不多说了,然后再来考虑如何计算
然后就结束了。时间复杂度:
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define il inline
#define re register
const int N=35100,K=60;
int n,k,a[N],res,cnt[N],dp[N][K],L,R;
il void init(){
for(re int i=0;i<=n;i++)for(re int j=0;j<=k;j++)dp[i][j]=-1;
dp[0][0]=0;
}
il void add(int x){
if(!cnt[x])res++;
cnt[x]++;
}
il void del(int x){
cnt[x]--;
if(!cnt[x])res--;
}
il int query(int l,int r){
while(L>l)add(a[--L]);
while(R<r)add(a[++R]);
while(L<l)del(a[L++]);
while(R>r)del(a[R--]);
return res;
}
il void solve(int l,int r,int optl,int optr,int id){
if(l>r)return;
int mid=(l+r)>>1,opt;
for(re int i=optl;i<=min(mid,optr);i++){
int tmp=dp[i-1][id-1]+query(i,mid);
if(tmp>dp[mid][id])dp[mid][id]=tmp,opt=i;
}
solve(l,mid-1,optl,opt,id);
solve(mid+1,r,opt,optr,id);
}
il int read(){
re int x=0,f=1;char c=getchar();
while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
while(c>='0'&&c<='9')x=(x<<3)+(x<<1)+(c^48),c=getchar();
return x*f;
}
int main(){
n=read(),k=read();
for(re int i=1;i<=n;i++)a[i]=read();
init();
for(re int i=1;i<=k;i++)solve(1,n,1,n,i);
cout<<dp[n][k];
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)