【CodeForces 426】div1 B The Bakery
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.
Input
4 1
1 2 2 1
Output
2
题解
设\(dp[k][n]\)表示k个分割的情况下最大收益
设\(C[i][j]\)表示区间(i,j)不同蛋糕的数量
对于只有k=1的情况
\]
对于k>1的情况
\]
如何求C数组?
对于每一个x,它能向左覆盖到上一个x的后一个位置,在这一部分,这个值都能提供贡献1。那么最终的value为所有点的覆盖中最大的值(即所有的x都有一个独立前缀,那么答案为这些独立前缀的交集最大者)
用线段树维护即可
import java.io.*;
import java.util.*;
public class Main {
static final int N=35005;
static int dp[][]=new int[55][N];
static int a[]=new int[N];
static int n,k;
static int max[]=new int[N<<2],tag[]=new int[N<<2];
static void build(int pos,int rt,int l,int r) {
tag[rt]=0;
if(l==r) {
max[rt]=dp[pos][l-1];
return;
}
int mid=(l+r)>>1;
build(pos,rt<<1,l,mid);
build(pos,rt<<1|1,mid+1,r);
max[rt]=Math.max(max[rt<<1],max[rt<<1|1]);
}
static void pushdown(int rt) {
if(tag[rt]<=0) return;
tag[rt<<1]+=tag[rt];
tag[rt<<1|1]+=tag[rt];
max[rt<<1]+=tag[rt];
max[rt<<1|1]+=tag[rt];
tag[rt]=0;
}
static void update(int L,int R,int rt,int l,int r) {
if(L<=l&&r<=R) {
tag[rt]++;
max[rt]++;
return;
}
pushdown(rt);
int mid=(l+r)>>1;
if(L<=mid) update(L,R,rt<<1,l,mid);
if(R>mid) update(L,R,rt<<1|1,mid+1,r);
max[rt]=Math.max(max[rt<<1],max[rt<<1|1]);
}
static int query(int L,int R,int rt,int l,int r) {
if(L<=l&&r<=R) {
return max[rt];
}
pushdown(rt);
int mid=(l+r)>>1,ret=0;
if(L<=mid) ret=Math.max(ret,query(L,R,rt<<1,l,mid));
if(R>mid) ret=Math.max(ret, query(L,R,rt<<1|1,mid+1,r));
max[rt]=Math.max(max[rt<<1], max[rt<<1|1]);
return ret;
}
static int pos[]=new int[N];
static int pre[]=new int[N];
public static void main(String[] args){
InputReader in = new InputReader(System.in);
PrintWriter out = new PrintWriter(System.out);
n=in.nextInt();k=in.nextInt();
Arrays.fill(pos,0,n+1,0);
Arrays.fill(pre,0,n+1,0);
for(int i=1;i<=n;i++) {
a[i]=in.nextInt();
pre[i]=pos[a[i]]+1;
pos[a[i]]=i;
}
Arrays.fill(dp[0],0,n+1,0);
for(int i=1;i<=k;i++) {
build(i-1,1,1,n);
for(int j=1;j<=n;j++) {
update(pre[j],j,1,1,n);
dp[i][j]=query(1,j,1,1,n);
}
}
out.println(dp[k][n]);
out.flush();
}
static class InputReader {
public BufferedReader reader;
public StringTokenizer tokenizer;
public InputReader(InputStream stream) {
reader = new BufferedReader(new InputStreamReader(stream), 32768);
tokenizer = null;
}
public String next() {
while (tokenizer == null || !tokenizer.hasMoreTokens()) {
try {
tokenizer = new StringTokenizer(reader.readLine());
} catch (IOException e) {
throw new RuntimeException(e);
}
}
return tokenizer.nextToken();
}
public int nextInt() {
return Integer.parseInt(next());
}
}
}
【CodeForces 426】div1 B The Bakery的更多相关文章
- 【codeforces 415D】Mashmokh and ACM(普通dp)
[codeforces 415D]Mashmokh and ACM 题意:美丽数列定义:对于数列中的每一个i都满足:arr[i+1]%arr[i]==0 输入n,k(1<=n,k<=200 ...
- 【codeforces 750C】New Year and Rating(做法2)
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【codeforces 750C】New Year and Rating
time limit per test2 seconds memory limit per test256 megabytes inputstandard input outputstandard o ...
- 【codeforces 707E】Garlands
[题目链接]:http://codeforces.com/contest/707/problem/E [题意] 给你一个n*m的方阵; 里面有k个联通块; 这k个联通块,每个连通块里面都是灯; 给你q ...
- 【codeforces 707C】Pythagorean Triples
[题目链接]:http://codeforces.com/contest/707/problem/C [题意] 给你一个数字n; 问你这个数字是不是某个三角形的一条边; 如果是让你输出另外两条边的大小 ...
- 【codeforces 709D】Recover the String
[题目链接]:http://codeforces.com/problemset/problem/709/D [题意] 给你一个序列; 给出01子列和10子列和00子列以及11子列的个数; 然后让你输出 ...
- 【codeforces 709B】Checkpoints
[题目链接]:http://codeforces.com/contest/709/problem/B [题意] 让你从起点开始走过n-1个点(至少n-1个) 问你最少走多远; [题解] 肯定不多走啊; ...
- 【codeforces 709C】Letters Cyclic Shift
[题目链接]:http://codeforces.com/contest/709/problem/C [题意] 让你改变一个字符串的子集(连续的一段); ->这一段的每个字符的字母都变成之前的一 ...
- 【Codeforces 429D】 Tricky Function
[题目链接] http://codeforces.com/problemset/problem/429/D [算法] 令Si = A1 + A2 + ... + Ai(A的前缀和) 则g(i,j) = ...
随机推荐
- websocket实现群聊
server # @File: 群聊 from flask import Flask, render_template, request from geventwebsocket.handler im ...
- _bzoj1029 [JSOI2007]建筑抢修【贪心 堆】
传送门:http://www.lydsy.com/JudgeOnline/problem.php?id=1029 经典的贪心问题,不解释. #include <cstdio> #inclu ...
- 洛谷 P1445 [Violet]樱花
#include<cstdio> #include<algorithm> #include<cstring> #include<vector> usin ...
- set+线段树 Codeforces Round #305 (Div. 2) D. Mike and Feet
题目传送门 /* 题意:对于长度为x的子序列,每个序列存放为最小值,输出长度为x的子序列的最大值 set+线段树:线段树每个结点存放长度为rt的最大值,更新:先升序排序,逐个添加到set中 查找左右相 ...
- 使用PreparedStatement接口
- Learn More Study Less `my notes`
整体性学习概念: 广泛扎实的基础知识 抽象知识成生活中的模型,便于记忆 融会贯通,创造新的东西 整体性学习组成 获取:积极阅读:标记并结合其他的知识点 主要观点 怎么记住:联系和比喻其他的知识 拓展和 ...
- python_面向对象(6)
第1章 递归函数 1.1 概述 1.2 练习 1.3 二分查找 第2章 面向对象•类 2.1 类的介绍 2.2 书写格式 2.3 类的属性 2.4 self介绍 2.5 类属性补充 2.6 调用查看静 ...
- solr facet查询及solrj 读取facet数据[转]
solr facet查询及solrj 读取facet数据 | 所属分类:solr facet solrj 一. Facet 简介 Facet 是 solr 的高级搜索功能之一 , 可以给用户提供更 ...
- js 获取最后一个字符
方法一: str.charAt(str.length - 1) 方法二: str.subStr(str.length-1,1) 方法三: var str = "123456" ...
- Java并发——ThreadPoolExecutor线程池解析及Executor创建线程常见四种方式
前言: 在刚学Java并发的时候基本上第一个demo都会写new Thread来创建线程.但是随着学的深入之后发现基本上都是使用线程池来直接获取线程.那么为什么会有这样的情况发生呢? new Thre ...