Portal

Description

给出一个\(n(n\leq35000)\)个数的数列\(\{a_i\}\)和\(m(m\leq50)\)。将原数列划分成\(m\)个连续的部分,每个部分的权值等于其中不同的数的个数。求所有划分方案中,所有部分权值和中的最大值。

Solution

线段树优化DP。

记录\(f[k][i]\)表示将前\(i\)个数划分为\(k\)段的最大权值和,\(w(i,j)\)表示\([L,R]\)的权值,那么容易列出转移方程:

\[ f[k][i]=max\{f[k-1][j]+w(j+1,i)\} \quad (0\leq j \leq i-1)$$ 复杂度为$O(n^2m)$。
考虑一下如何简化$w$。记录$a_x$上一次出现的位置为$pre_x$,则$a_x$为$pre_x+1\leq i \leq x$的$w(i,x)$提供了$1$的贡献。那么我们如果想从$w(i,x-1)$转移到$w(i,x)$,只需对区间$[pre_x+1,x]$加$1$即可。
那么我们要做的就是维护$f[k-1][j]+w(j+1,i)$的区间最值,用线段树即可。第二维由$i$变为$i+1$时,对线段树进行一次区间加即可。
> 时间复杂度$O(nk\cdot logn)$。

##Code
```cpp
//The Bakery
#include <cstdio>
inline char gc()
{
static char now[1<<16],*s,*t;
if(s==t) {t=(s=now)+fread(now,1,1<<16,stdin); if(s==t) return EOF;}
return *s++;
}
inline int read()
{
int x=0; char ch=gc();
while(ch<'0'||'9'<ch) ch=gc();
while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=gc();
return x;
}
inline int max(int x,int y) {return x>y?x:y;}
const int N=4e4;
int n,m,a[N];
int pre[N],pre1[N];
#define Ls (p<<1)
#define Rs (p<<1|1)
const int N1=N<<2;
int rt,val[N1]; int add[N1];
void update(int p) {val[p]=max(val[Ls],val[Rs]);}
void addV(int p,int v) {add[p]+=v,val[p]+=v;}
void pushdw(int p) {if(add[p]) addV(Ls,add[p]),addV(Rs,add[p]),add[p]=0;}
int optL,optR;
void ins(int p,int L0,int R0,int v,int type)
{
if(optL<=L0&&R0<=optR)
{
if(type==1) addV(p,v);
else val[p]=v;
return;
}
pushdw(p);
int mid=L0+R0>>1;
if(optL<=mid) ins(Ls,L0,mid,v,type);
if(mid<optR) ins(Rs,mid+1,R0,v,type);
update(p);
}
int query(int p,int L0,int R0)
{
if(optL<=L0&&R0<=optR) return val[p];
pushdw(p);
int mid=L0+R0>>1; int r=0;
if(optL<=mid) r=max(r,query(Ls,L0,mid));
if(mid<optR) r=max(r,query(Rs,mid+1,R0));
return r;
}
int f[N];
int main()
{
n=read(),m=read();
for(int i=1;i<=n;i++)
{
a[i]=read();
pre[i]=pre1[a[i]],pre1[a[i]]=i;
}
rt=1;
for(int k=1;k<=m;k++)
{
for(int i=k;i<=n;i++)
{
optL=pre[i],optR=i-1,ins(rt,0,n,1,1);
optL=0,optR=i-1,f[i]=query(rt,0,n);
}
if(k==m) break;
for(int i=0;i<=n;i++) optL=optR=i,ins(rt,0,n,f[i],2);
}
printf("%d\n",f[n]);
return 0;
}
```\]

Codeforces834D - The Bakery的更多相关文章

  1. Codeforeces 707B Bakery(BFS)

    B. Bakery time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

  2. Codeforces Round #368 (Div. 2) B. Bakery (模拟)

    Bakery 题目链接: http://codeforces.com/contest/707/problem/B Description Masha wants to open her own bak ...

  3. 信号量和PV操作写出Bakery算法的同步程序

    面包店烹制面包及蛋糕,由n个销售员卖出.当有顾客进店购买面包或蛋糕时,应先在取号机上取号,然后等待叫号,若有销售员空闲时便叫下一号,试用信号量和PV操作写出Bakery算法的同步程序. 设计要求 1) ...

  4. Codeforces 834D The Bakery【dp+线段树维护+lazy】

    D. The Bakery time limit per test:2.5 seconds memory limit per test:256 megabytes input:standard inp ...

  5. Codeforces 834D The Bakery - 动态规划 - 线段树

    Some time ago Slastyona the Sweetmaid decided to open her own bakery! She bought required ingredient ...

  6. Codeforces Round #426 (Div. 1) B The Bakery (线段树+dp)

    B. The Bakery time limit per test 2.5 seconds memory limit per test 256 megabytes input standard inp ...

  7. Codeforces Round #368 (Div. 2) B. Bakery 水题

    B. Bakery 题目连接: http://www.codeforces.com/contest/707/problem/B Description Masha wants to open her ...

  8. Codeforces 834D - The Bakery(dp+线段树)

    834D - The Bakery 思路:dp[i][j]表示到第j个数为止分成i段的最大总和值. dp[i][j]=max{dp[i-1][x]+c(x+1,j)(i-1≤x≤j-1)},c(x+1 ...

  9. CF833B The Bakery 线段树,DP

    CF833B The Bakery LG传送门 线段树优化DP. 其实这是很久以前就应该做了的一道题,由于颓废一直咕在那里,其实还是挺不错的一道题. 先考虑\(O(n^2k)\)做法:设\(f[i][ ...

随机推荐

  1. NHibernate使用之详细图解

    本文档适合初级开发者或者是第一次接触NHibernate框架的朋友,其中NHibernate不是最新的版本,但是一个比较经典的版本 NHibernate 2.1.2,其中用红线标注的部分一定要仔细看, ...

  2. 树莓派 - 修改pi账号密码,开启root账号

    1.修改PI账号的密码 password pi 2.开启root账号 树莓派使用的Linux是debian系统,所以树莓派启用root和debian是相同的. debian里root账户默认没有密码, ...

  3. LINQ与反射

    string file = @"C:\Windows\winsxs\x86_netfx35linq-system.core_31bf3856ad364e35_6.1.7601.17514_n ...

  4. HDU-4848-Such Conquering

    这题就是深搜加剪枝,有一个很明显的剪枝,因为题目中给出了一个deadline,所以我们一定要用这个deadline来进行剪枝. 题目的意思是求到达每个点的时间总和,当时把题看错了,卡了好久. 剪枝一: ...

  5. 深入理解 hashcode 和 hash 算法

    深入理解 hashcode 和 hash 算法 2017年12月30日 23:06:07 阅读数:5197 标签: hashhashmaphashcode二进制 更多 个人分类: jdk-源码  ht ...

  6. redis学习笔记(3)

    redis学习笔记第三部分 --redis持久化介绍,事务,主从复制 三,redis的持久化 RDB(Redis DataBase)AOF(Append Only File) RDB:在指定的时间间隔 ...

  7. 06grep与find命令详解

    1. grep 命令 grep 命令用于在文本中执行关键词搜索,并显示匹配的结果,格式为"grep [选项][文件]". grep 命令的参数及其作用如下: -b 将可执行文件(b ...

  8. Qt概念和快捷键

    Qt概念和快捷键 Qt简介        1.Qt的由来和发展 Qt是一个1991年由Qt Company开发的跨平台C++图形用户界面应用程序开发框架.它既可以开发GUI程序,也可用于开发非GUI程 ...

  9. RSA与AES实现数据加密传输

    RSA.AES简介 RSA:非对称加密,需要提前生成两个密钥(一对的),通过其中一个密钥加密后的数据,只有另一个密钥能解密.通常这两个密钥中有一个会暴漏出来,即对外公开的,这个密钥称为“公钥”,反之另 ...

  10. SQL登录注册练习

    /class User package com.neusoft.bean; public class User { private int password; private String name; ...