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$裸题.. 先去掉所有能被其他线段包含的线段,这种线段一定不在最优解里 ...
随机推荐
- [原创] debian 9.3 搭建Jira+Confluence+Bitbucket项目管理工具(二) -- 安装jira 7.5.4
[原创] debian 9.3 搭建Jira+Confluence+Bitbucket项目管理工具(二) -- 安装jira 7.5.4 环境都配置好以后, 开始搭建Jira的环境, 这里参考了一篇文 ...
- cmake: error: symbol(s) not found for architecture x86_64 mac os 使用boost asio
最近在使用boost的asio库,在mac osx 上编写网络服务程序报错: :-1: error: symbol(s) not found for architecture x86_64 然后在CM ...
- 一个box四周边框阴影
实现效果如图: 代码如下: .section { margin: 20upx 30upx; padding: 40upx; border-radius: 6px; border-top: #0670C ...
- margin居中显示
标签(空格分隔): margin居中 margin居中: 如下图的代码查看: <!DOCTYPE html> <html lang="en"> <he ...
- 认识border
标签(空格分隔): border border的认识: border:边框的意思,描述盒子的边框,边框有三个要素: 粗细, 线性样式 ,颜色: <!DOCTYPE html> <ht ...
- HDFS中将普通用户增加到超级用户组supergroup
- python--第十五天总结(jquery)
空格:$('parent childchild')表示获取parent下的所有的childchild节点,所有的子孙. 大于号:$('parent > child')表示获取parent下的所有 ...
- Selenium 实现nvsm查询和输出ksql语句
测试环境:http://nvsm.cnki.net/kns/brief/result.aspx?dbprefix=SCDB 程序功能:对各个文献库的高级检索功能,输入检索条件做检索,提取加密的ksql ...
- Exp4 恶意代码分析 20165110
Exp4 恶意代码分析 20165110 一.实践目标 1.是监控你自己系统的运行状态,看有没有可疑的程序在运行. 2.是分析一个恶意软件,就分析Exp2或Exp3中生成后门软件:分析工具尽量使用原生 ...
- pandas和re中正则表达式的意思
这里()有两种意思,第一个就是表示匹配范围,另外一个就是输出这个匹配 下面那条语句就是告诉程序,是输出整个句子,“?:”非获取匹配,匹配冒号后的内容但不获取匹配结果,不进行存储供以后使用.