ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

CF868F Yet Another Minimization Problem

2021-04-24 09:02:22  阅读:188  来源: 互联网

标签:Minimization int CF868F mid -- ls Problem dp define


题面传送门
显然有一眼\(O(n^2k)\)的dp:设\(dp_{i,j}\)为分了\(i\)段,分到第\(j\)个时的最小值。
那么可以\(O(n)\)暴力转移。
因为每种颜色相互独立,所以我们对每种颜色分别考虑。
如果\([i,j]\)中有\(x\)个,\([i',j']\)中有\(y\)个,\([i,j']\)中有\(z\)个,那么\([i',j]\)里有\(x+y-z\)个。
展开一下就可以发现这个满足决策单调性。
又因为这个不从自己转移,所以可以用分治法解决。
转移时像莫队一样暴力移动即可。
时间复杂度\(O(nklogn)\)
code:

#include<cstdio>
#include<cstring> 
#define N 100000
#define I inline
#define re register
#define ll long long
#define min(a,b) ((a)<(b)?(a):(b))
#define max(a,b) ((a)>(b)?(a):(b)) 
using namespace std;
int n,k,a[N+5],f[N+5],ls=1,rs;ll w,g[N+5],dp[N+5]; 
I void get(int l,int r){
	while(ls>l) w+=f[a[--ls]]++;
	while(rs<r) w+=f[a[++rs]]++;
	while(ls<l) w-=--f[a[ls++]];
	while(rs>r) w-=--f[a[rs--]];
}
I void solve(int l,int r,int x,int y){
	if(x>y) return;int mid=x+y>>1,i,p=mid,nowl=ls,nowr=rs;
	for(i=min(mid,r);i>=l;i--) get(i,mid),dp[mid]>g[i-1]+w&&(dp[mid]=g[i-1]+w,p=i);
	solve(l,p,x,mid-1);solve(p,r,mid+1,y);get(nowl,nowr);
}
int main(){
	freopen("1.in","r",stdin);
	re int i,j;scanf("%d%d",&n,&k);memset(dp,0x3f,sizeof(dp));dp[0]=0;
	for(i=1;i<=n;i++) scanf("%d",&a[i]);
	for(i=1;i<=k;i++){
		for(j=1;j<=n;j++) g[j]=dp[j];solve(1,n,1,n);
	}
	printf("%lld\n",dp[n]);
}

标签:Minimization,int,CF868F,mid,--,ls,Problem,dp,define
来源: https://www.cnblogs.com/275307894a/p/14696179.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有