The Bakery
time limit per test

2.5 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

Some time ago Slastyona the Sweetmaid decided to open her own bakery! She bought required ingredients and a wonder-oven which can bake several types of cakes, and opened the bakery.

Soon the expenses started to overcome the income, so Slastyona decided to study the sweets market. She learned it's profitable to pack cakes in boxes, and that the more distinct cake types a box contains (let's denote this number as the value of the box), the higher price it has.

She needs to change the production technology! The problem is that the oven chooses the cake types on its own and Slastyona can't affect it. However, she knows the types and order of n cakes the oven is going to bake today. Slastyona has to pack exactly k boxes with cakes today, and she has to put in each box several (at least one) cakes the oven produced one right after another (in other words, she has to put in a box a continuous segment of cakes).

Slastyona wants to maximize the total value of all boxes with cakes. Help her determine this maximum possible total value.

Input

The first line contains two integers n and k (1 ≤ n ≤ 35000, 1 ≤ k ≤ min(n, 50)) – the number of cakes and the number of boxes, respectively.

The second line contains n integers a1, a2, ..., an (1 ≤ ai ≤ n) – the types of cakes in the order the oven bakes them.

Output

Print the only integer – the maximum total value of all boxes with cakes.

Examples
input
4 1
1 2 2 1
output
2
input
7 2
1 3 3 1 4 4 4
output
5
input
8 3
7 7 8 7 7 8 1 7
output
6
Note

In the first example Slastyona has only one box. She has to put all cakes in it, so that there are two types of cakes in the box, so the value is equal to 2.

In the second example it is profitable to put the first two cakes in the first box, and all the rest in the second. There are two distinct types in the first box, and three in the second box then, so the total value is 5.

【题意】给你一个序列,然后在原来的顺序基础上将这些数分成K份,每一份至少一个数,然后对于每一份,将数的种数累加,求累加和最大值。

【分析】如果n小一些的话,我们可以n方DP做,DP[i][j]表示在i这个地方将前面分成k份的最大值,那么dp[i][j]=dp[k][j-1]+(k+1~j的数的种数),

但是N太大。。。于是我们想到线段树。线段树的维护这个区间内每一个位置的dp值+这个位置到我当前dp到的位置的数的种数,然后对这个区间取最大值。当我们dp到i时,我们将a[i]上一次出现的位置+1~i这个区间更新+1,然后查询1~i的最大值即可。

#include <bits/stdc++.h>
#define inf 0x3f3f3f3f
#define met(a,b) memset(a,b,sizeof a)
#define pb push_back
#define mp make_pair
#define inf 0x3f3f3f3f
using namespace std;
typedef long long ll;
const int N = 3e4+;;
const int M = ;
const int mod = 1e9+;
const double pi= acos(-1.0);
typedef pair<int,int>pii;
int n,k,ans;
int a[N],mx[N*],lazy[N*];
int pre[N],pos[N],dp[N];
void pushUp(int rt){
mx[rt]=max(mx[rt<<],mx[rt<<|]);
}
void pushDown(int rt){
if(lazy[rt]){
lazy[rt<<]+=lazy[rt];
lazy[rt<<|]+=lazy[rt];
mx[rt<<]+=lazy[rt];
mx[rt<<|]+=lazy[rt];
lazy[rt]=;
}
}
void build(int l,int r,int rt){
lazy[rt]=;
if(l==r){
mx[rt]=dp[l-];
return;
}
int mid=(l+r)>>;
build(l,mid,rt<<);
build(mid+,r,rt<<|);
pushUp(rt);
}
void upd(int L,int R,int l,int r,int x,int rt){
if(L<=l&&r<=R){
mx[rt]+=x;
lazy[rt]+=x;
return;
}
pushDown(rt);
int mid=(l+r)>>;
if(L<=mid)upd(L,R,l,mid,x,rt<<);
if(R>mid) upd(L,R,mid+,r,x,rt<<|);
pushUp(rt);
}
int qry(int L,int R,int l,int r,int rt){
if(L<=l&&r<=R){
return mx[rt];
}
pushDown(rt);
int ret=,mid=(l+r)>>;
if(L<=mid)ret=max(ret,qry(L,R,l,mid,rt<<));
if(R>mid)ret=max(ret,qry(L,R,mid+,r,rt<<|));
return ret;
}
int main(){
scanf("%d%d",&n,&k);
for(int i=;i<=n;i++){
scanf("%d",&a[i]);
pre[i]=pos[a[i]];
pos[a[i]]=i;
}
for(int i=;i<=k;i++){
build(,n,);
for(int j=;j<=n;j++){
upd(pre[j]+,j,,n,,);
dp[j]=qry(,j,,n,);
}
}
printf("%d\n",dp[n]);
}

Codeforces Round #426 (Div. 2) D The Bakery(线段树 DP)的更多相关文章

  1. 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 ...

  2. Codeforces Round #587 (Div. 3) F Wi-Fi(线段树+dp)

    题意:给定一个字符串s 现在让你用最小的花费 覆盖所有区间 思路:dp[i]表示前i个全覆盖以后的花费 如果是0 我们只能直接加上当前位置的权值 否则 我们可以区间询问一下最小值 然后更新 #incl ...

  3. 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 ...

  4. Codeforces Round #603 (Div. 2) E. Editor(线段树)

    链接: https://codeforces.com/contest/1263/problem/E 题意: The development of a text editor is a hard pro ...

  5. Codeforces Round #244 (Div. 2) B. Prison Transfer 线段树rmq

    B. Prison Transfer Time Limit: 20 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/problemset/pro ...

  6. 【动态规划】【线段树】 Codeforces Round #426 (Div. 1) B. The Bakery

    给你一个序列,让你划分成K段,每段的价值是其内部权值的种类数,让你最大化所有段的价值之和. 裸dp f(i,j)=max{f(k,j-1)+w(k+1,i)}(0<=k<i) 先枚举j,然 ...

  7. Codeforces Round #546 (Div. 2) E 推公式 + 线段树

    https://codeforces.com/contest/1136/problem/E 题意 给你一个有n个数字的a数组,一个有n-1个数字的k数组,两种操作: 1.将a[i]+x,假如a[i]+ ...

  8. Codeforces Round #222 (Div. 1) D. Developing Game 线段树有效区间合并

    D. Developing Game   Pavel is going to make a game of his dream. However, he knows that he can't mak ...

  9. Codeforces Round #275 Div.1 B Interesting Array --线段树

    题意: 构造一个序列,满足m个形如:[l,r,c] 的条件. [l,r,c]表示[l,r]中的元素按位与(&)的和为c. 解法: 线段树维护,sum[rt]表示要满足到现在为止的条件时该子树的 ...

随机推荐

  1. jsp 内置对象(一)

    一.jsp的九大内置对象 内置对象 所属类 pageContext javax.servlet.jsp.PageContext request javax.servlet.http.HttpServl ...

  2. gpio子系统和pinctrl子系统(下)

    情景分析 打算从两个角度来情景分析,先从bsp驱动工程师的角度,然后是驱动工程师的角度,下面以三星s3c6410 Pinctrl-samsung.c为例看看pinctrl输入参数的初始化过程(最开始的 ...

  3. 64_k1

    KoboDeluxe-0.5.1-22.fc26.x86_64.rpm 13-Feb-2017 22:11 1626454 k3b-17.04.1-1.fc26.x86_64.rpm 25-May-2 ...

  4. quazip 在windows msvc 2005 下的编译

    quazip 在windows  msvc 2005 下的编译 http://blog.csdn.net/v6543210/article/details/11661427

  5. bzoj 1798 维护序列seq

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1798 题解: 高级一点的线段树,加上了区间乘法运算,则需要增加一个数组mulv记录乘的因数 ...

  6. jquery - 实例1

    <%@ Page Language="C#" AutoEventWireup="true" CodeBehind="text2.aspx.cs& ...

  7. 《Java编程思想》阅读笔记一

    Java编程思想 这是一个通过对<Java编程思想>(Think in java)第四版进行阅读同时对java内容查漏补缺的系列.一些基础的知识不会被罗列出来,这里只会列出一些程序员经常会 ...

  8. Java Socket编程基础篇

    原文地址:Java Socket编程----通信是这样炼成的 Java最初是作为网络编程语言出现的,其对网络提供了高度的支持,使得客户端和服务器的沟通变成了现实,而在网络编程中,使用最多的就是Sock ...

  9. phpcms v9表单向导添加验证码

    要做留言板的功能,故用添加表单,想要在提交留言前加一个验证码的功能.网上的教程比较混乱,于是亲自实验了下,步骤如下: 首先是调用表单的页面加入验证码.表单js调用模版默认的是 \phpcms\temp ...

  10. js 获取html5的data属性

    我以前一直以为只能用jquery的data()来获取 哈哈 是我太弱了 <!DOCTYPE html> <html> <head> <title>dat ...