2019.03.09 codeforces833B. The Bakery(线段树优化dp)
传送门
线段树优化dpdpdp入门题。
要求把nnn个数分成kkk段,每段价值为里面不相同的数的个数,求所有段的价值之和最大值。n≤35000,k≤50n\le35000,k\le50n≤35000,k≤50
先考虑直接暴力dpdpdp,fj,if_{j,i}fj,i表示把前iii个分成jjj组的最优值。
显然fj,i=maxj−1≤k≤i−1{fj−1,k+W(k+1,i)}f_{j,i}=\max\limits_{j-1\le k\le i-1}\{f_{j-1,k}+W(k+1,i)\}fj,i=j−1≤k≤i−1max{fj−1,k+W(k+1,i)}
于是就有了一个O(n2k)O(n^2k)O(n2k)的做法。
现在考虑优化求fj,i+W(k+1,i)f_{j,i}+W(k+1,i)fj,i+W(k+1,i)的做法。
我们考虑增量法,即枚举当前层的iii的时候考虑coloricolor_icolori对之前所有的fff的贡献。
对于这种相同颜色只考虑一次贡献的题有这么一个固定的套路:我们记当前颜色上一次出现的位置为pre,则这个颜色会对[pre+1,i]或者[pre,i-1]这一段产生贡献。
对于这道题可以动态维护fj−1,k+W(k+1,j)f_{j-1,k}+W(k+1,j)fj−1,k+W(k+1,j)这个值,因此我们最开始将fj−1,if_{j-1,i}fj−1,i全部放到一棵线段树上面作为初始值,走到位置iii时把[prei,i−1][pre_i,i-1][prei,i−1]维护的值全部加111即可。
代码:
#include<bits/stdc++.h>
#define ri register int
using namespace std;
inline int read(){
int ans=0;
char ch=getchar();
while(!isdigit(ch))ch=getchar();
while(isdigit(ch))ans=(ans<<3)+(ans<<1)+(ch^48),ch=getchar();
return ans;
}
const int N=35005,K=55;
int tmp=0,a[N],f[2][N],n,k,pre[N],mp[N];
namespace SGT{
#define lc (p<<1)
#define rc (p<<1|1)
#define mid (l+r>>1)
int mx[N<<2],add[N<<2];
inline void pushup(int p){mx[p]=max(mx[lc],mx[rc]);}
inline void pushnow(int p,int v){mx[p]+=v,add[p]+=v;}
inline void pushdown(int p){if(add[p])pushnow(lc,add[p]),pushnow(rc,add[p]),add[p]=0;}
inline void build(int p,int l,int r){
add[p]=0;
if(l==r){mx[p]=f[tmp^1][l];return;}
build(lc,l,mid),build(rc,mid+1,r),pushup(p);
}
inline void update(int p,int l,int r,int ql,int qr,int v){
if(ql>qr)return;
if(ql<=l&&r<=qr)return pushnow(p,v);
pushdown(p);
if(qr<=mid)update(lc,l,mid,ql,qr,v);
else if(ql>mid)update(rc,mid+1,r,ql,qr,v);
else update(lc,l,mid,ql,mid,v),update(rc,mid+1,r,mid+1,qr,v);
pushup(p);
}
inline int query(int p,int l,int r,int ql,int qr){
if(ql>qr)return -0x3f3f3f3f;
if(ql<=l&&r<=qr)return mx[p];
pushdown(p);
if(qr<=mid)return query(lc,l,mid,ql,qr);
if(ql>mid)return query(rc,mid+1,r,ql,qr);
return max(query(lc,l,mid,ql,mid),query(rc,mid+1,r,mid+1,qr));
}
#undef lc
#undef rc
#undef mid
}
int main(){
n=read(),k=read();
memset(mp,-1,sizeof(mp));
for(ri i=1;i<=n;++i)a[i]=read(),pre[i]=mp[a[i]],mp[a[i]]=i;
memset(f[tmp],-0x3f,sizeof(f[tmp]));
f[tmp][0]=0;
for(ri tt=1;tt<=k;++tt){
tmp^=1;
memset(f[tmp],-0x3f,sizeof(f[tmp]));
SGT::build(1,0,n);
for(ri i=1;i<=n;++i){
SGT::update(1,0,n,pre[i],i-1,1);
f[tmp][i]=SGT::query(1,0,n,tt-1,i-1);
}
}
cout<<f[tmp][n];
return 0;
}
2019.03.09 codeforces833B. The Bakery(线段树优化dp)的更多相关文章
- CodeForces 834D The Bakery(线段树优化DP)
Some time ago Slastyona the Sweetmaid decided to open her own bakery! She bought required ingredient ...
- Codeforces Round #426 (Div. 2) D. The Bakery 线段树优化DP
D. The Bakery Some time ago Slastyona the Sweetmaid decided to open her own bakery! She bought req ...
- CF833B The Bakery 线段树,DP
CF833B The Bakery LG传送门 线段树优化DP. 其实这是很久以前就应该做了的一道题,由于颓废一直咕在那里,其实还是挺不错的一道题. 先考虑\(O(n^2k)\)做法:设\(f[i][ ...
- D - The Bakery CodeForces - 834D 线段树优化dp···
D - The Bakery CodeForces - 834D 这个题目好难啊,我理解了好久,都没有怎么理解好, 这种线段树优化dp,感觉还是很难的. 直接说思路吧,说不清楚就看代码吧. 这个题目转 ...
- Codeforces Round #426 (Div. 2) D 线段树优化dp
D. The Bakery time limit per test 2.5 seconds memory limit per test 256 megabytes input standard inp ...
- BZOJ2090: [Poi2010]Monotonicity 2【线段树优化DP】
BZOJ2090: [Poi2010]Monotonicity 2[线段树优化DP] Description 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k]. ...
- [AGC011F] Train Service Planning [线段树优化dp+思维]
思路 模意义 这题真tm有意思 我上下楼梯了半天做出来的qwq 首先,考虑到每K分钟有一辆车,那么可以把所有的操作都放到模$K$意义下进行 这时,我们只需要考虑两边的两辆车就好了. 定义一些称呼: 上 ...
- 【bzoj3939】[Usaco2015 Feb]Cow Hopscotch 动态开点线段树优化dp
题目描述 Just like humans enjoy playing the game of Hopscotch, Farmer John's cows have invented a varian ...
- POJ 2376 Cleaning Shifts (线段树优化DP)
题目大意:给你很多条线段,开头结尾是$[l,r]$,让你覆盖整个区间$[1,T]$,求最少的线段数 题目传送门 线段树优化$DP$裸题.. 先去掉所有能被其他线段包含的线段,这种线段一定不在最优解里 ...
随机推荐
- 排序大集合java
今日面试被问到排序问题,发现自己的不足,特来查漏补缺: 首先是各大排序算法的总结表 排序算法大合集 排序算法 平均时间复杂度 最好情况 最坏情况 空间复杂度 稳定性 冒泡排序 Ο(n2) Ο(n) ...
- laravel passport加密jwt格式的access_token中的sub(user_id)字段
在很多需求我们不希望别人知道用户在我们表中的 user_id :但是又想用数据库的自增 id 功能:一般时候在取出用户后加密 user_id 加密即可:但是总有那么几个不经意间就可能把我们的 user ...
- Redis 数据类型归纳
Redis的数据类型从整体上看,都是Key-Value键值对的模型,数据类型更确切地说,应该是Value的数据类型,比如string,set,list等,都是key值对应的Value的数据集合格式.不 ...
- ansible批量自动安装LNMP
- nodejs设置跨域访问
//设置跨域访问app.all('*', function(req, res, next) { res.header("Access-Control-Allow-Origin", ...
- vue项目结构搭建
1安装node.js,已集成npm 2.临时使用淘宝镜像 npm --registry https://registry.npm.taobao.org install express 3.instal ...
- Numpy一文全了解
1,Numpy是一个python包,它是一个由多维数组对象和处理数组的例程集合组成的库. 2. Numpy的操作:(1)数组的算数和逻辑运算 :(2)傅里叶变换和用于图形操作 (3)与线性代数有 ...
- Spring:事务
摘要 本文摘抄了Spring事务相关的一些理论,主要讲述事务的特性.事务的传播行为.事务的隔离规则. 关键词:事务特性,事务传播,事务隔离 一.什么是事务 事务是用来保证数据的完整性和一致性,正如金钱 ...
- Android辅助开发工具合集
https://github.com/389273716/android-skill-summary/blob/master/开发工具使用指南/辅助开发工具.md
- js及vue监听键盘回车事件
js document.onkeydown = (event) => { var e = event || window.event; if(e && e.keyCode==13 ...