Codeforces Round #426 (Div. 2) D 线段树优化dp
2.5 seconds
256 megabytes
standard input
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.
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.
Print the only integer – the maximum total value of all boxes with cakes.
4 1
1 2 2 1
2
7 2
1 3 3 1 4 4 4
5
8 3
7 7 8 7 7 8 1 7
6
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.
题意:给你一个长度为n的序列 现在可以分成k部分 求每部分不同数的个数的和的最大值
题解:线段树优化dp
dp[i][j] 表示前j个分成i部分的最大值
#pragma comment(linker, "/STACK:102400000,102400000")
#include <bits/stdc++.h>
#include <cstdlib>
#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <cctype>
#include <map>
#include <set>
#include <queue>
#include <bitset>
#include <string>
#include <complex>
#define LL long long
#define mod 1000000007
using namespace std;
int n,k;
int a[];
int last[];
int dp[][];
map<int,int> mp;
struct node{
int l,r;
int maxn;
int add;
} tree[];
void buildtree(int root ,int left,int right,int p){
tree[root].l=left;
tree[root].r=right;
tree[root].add=;
tree[root].maxn=;
if(left==right){
tree[root].maxn=dp[p][left-];//将当前结点的最大值 初始为 前(left-1)个分成p部分的最大值
return ;
}
int mid=(left+right)>>;
buildtree(root<<,left,mid,p);
buildtree(root<<|,mid+,right,p);
tree[root].maxn=max(tree[root<<].maxn,tree[root<<|].maxn);
}
void pushdown(int root)
{
if(tree[root].add==) return ;
tree[root<<].add+=tree[root].add;
tree[root<<|].add+=tree[root].add;
tree[root<<].maxn+=tree[root].add;
tree[root<<|].maxn+=tree[root].add;
tree[root].add=;
}
void update(int root,int left,int right,int c)
{
if(tree[root].l==left&&tree[root].r==right)
{
tree[root].add+=c;
tree[root].maxn+=c;
return ;
}
pushdown(root);
int mid=(tree[root].l+tree[root].r)>>;
if(right<=mid)
{
update(root<<,left,right,c);
}
else
{
if(left>mid)
update(root<<|,left,right,c);
else
{
update(root<<,left,mid,c);
update(root<<|,mid+,right,c); }
}
tree[root].maxn=max(tree[root<<].maxn,tree[root<<|].maxn);
}
int query(int root,int left,int right)
{
if(left>right)
return ;
if(tree[root].l==left&&tree[root].r==right)
{
return tree[root].maxn;
}
pushdown(root);
int mid=(tree[root].l+tree[root].r)>>;
if(right<=mid)
return query(root<<,left,right);
else
{
if(left>mid)
return query(root<<|,left,right);
else
return max(query(root<<,left,mid),query(root<<|,mid+,right));
}
}
int main()
{
scanf("%d %d",&n,&k);
for(int i=; i<=n; i++){
scanf("%d",&a[i]);
last[i]=mp[a[i]];
mp[a[i]]=i;
}
for(int i=;i<=k;i++){
buildtree(,,n,i-);//
for(int j=;j<=n;j++){
update(,max(last[j]+,),j,); //第j个只能在 (max(last[j]+1,1),j) 做贡献
dp[i][j]=query(,,j);
}
}
printf("%d\n",dp[k][n]);
return ;
}
Codeforces Round #426 (Div. 2) D 线段树优化dp的更多相关文章
- Codeforces Round #530 (Div. 2) F 线段树 + 树形dp(自下往上)
https://codeforces.com/contest/1099/problem/F 题意 一颗n个节点的树上,每个点都有\(x[i]\)个饼干,然后在i节点上吃一个饼干的时间是\(t[i]\) ...
- Codeforces #426 Div2 D(线段树优化 DP )
#426 Div2 D 题意 给出 \(n\) 个数字,将这些数字隔成 \(k\) 个部分(相对位置不变),统计每个部分有几个不同数字,然后全部加起来求和,问和最大是多少. 分析 很容易想到 \(DP ...
- Please, another Queries on Array?(Codeforces Round #538 (Div. 2)F+线段树+欧拉函数+bitset)
题目链接 传送门 题面 思路 设\(x=\prod\limits_{i=l}^{r}a_i\)=\(\prod\limits_{i=1}^{n}p_i^{c_i}\) 由欧拉函数是积性函数得: \[ ...
- Nastya Hasn't Written a Legend(Codeforces Round #546 (Div. 2)E+线段树)
题目链接 传送门 题面 题意 给你一个\(a\)数组和一个\(k\)数组,进行\(q\)次操作,操作分为两种: 将\(a_i\)增加\(x\),此时如果\(a_{i+1}<a_i+k_i\),那 ...
- CodeCraft-19 and Codeforces Round #537 (Div. 2) E 虚树 + 树形dp(新坑)
https://codeforces.com/contest/1111/problem/E 题意 一颗有n个点的树,有q个询问,每次从树挑出k个点,问将这k个点分成m组,需要保证在同一组中不存在一个点 ...
- CodeForces 834C - The Meaningless Game | Codeforces Round #426 (Div. 2)
/* CodeForces 834C - The Meaningless Game [ 分析,数学 ] | Codeforces Round #426 (Div. 2) 题意: 一对数字 a,b 能不 ...
- D - The Bakery CodeForces - 834D 线段树优化dp···
D - The Bakery CodeForces - 834D 这个题目好难啊,我理解了好久,都没有怎么理解好, 这种线段树优化dp,感觉还是很难的. 直接说思路吧,说不清楚就看代码吧. 这个题目转 ...
- Codeforces 1603D - Artistic Partition(莫反+线段树优化 dp)
Codeforces 题面传送门 & 洛谷题面传送门 学 whk 时比较无聊开了道题做做发现是道神题( 介绍一种不太一样的做法,不观察出决策单调性也可以做. 首先一个很 trivial 的 o ...
- BZOJ2090: [Poi2010]Monotonicity 2【线段树优化DP】
BZOJ2090: [Poi2010]Monotonicity 2[线段树优化DP] Description 给出N个正整数a[1..N],再给出K个关系符号(>.<或=)s[1..k]. ...
随机推荐
- java后端面试题汇总
转载链接:https://www.nowcoder.com/discuss/90776?type=0&order=0&pos=23&page=0 基础篇 数据结构与算法 线性表 ...
- Centos7 Jenkins
代码上线 持续集成 随时随地将代码合并,这种方法叫做持续集成. 持续集成(CONTINUOUS INTEGRATION,简称CI)持续集成指的是,频繁地(一天多次)将代码集成到主干.它的好处主要有两个 ...
- paste命令详解
基础命令学习目录首页 原文链接:https://blog.csdn.net/u011341352/article/details/52806312 个人分类: linux paste命令和cut命 ...
- Python图形界面开发—wxPython库的布局管理及页面切换
前言 wxPython是基于Python的跨平台GUI扩展库,对wxWidgets( C++ 编写)封装实现.GUI程序的开发中界面布局是很重要的一个部分,合理的页面布局能够给予用户良好使用体验.虽然 ...
- Python20 - Day09
python并发编程之多线程理论 1.什么是线程? 进程只是用来把资源集中到一起(进程是一个资源单位,或者说资源集合),而线程才是cpu上的执行单位. 多线程(多个控制线程)的概念是,在一个进程中存在 ...
- 详解HTTP缓存
HTTP缓存是个大公司面试几乎必考的问题,写篇随笔说一下HTTP缓存. 1. HTTP报文首部中有关缓存的字段 在HTTP报文中,与缓存相关的信息都存在首部里,简单说一下首部. 首部 HTTP首部字段 ...
- 20162328蔡文琛 大二week07
20162328 2017-2018-1 <程序设计与数据结构>第7周学习总结 教材学习内容总结 树是非线性结构,其元素组织为一个层次结构. 树的度表示树种任意节点的最大子节点数. 有m个 ...
- 团队冲刺——Five
昨天: 司宇航:web项目如何部署到公网,把网址做成桌面图标链接,登录记住密码功能. 王金萱:注册和登录界面,用户数据库的信息录入. 马佳慧:做界面. 季方:处理爬虫数据,实现统计功能. 遇到的问题: ...
- iOS开发学习-NSUserDefaults的介绍和用法
NSUserDefaults类提供了一个与默认系统进行交互的编程接口.NSUserDefaults对象是用来保存,恢复应用程序相关的偏好设置,配置数据等等.默认系统允许应用程序自定义它的行为去迎合用户 ...
- cocos2d-x 相关文章资源(安卓开发)
http://blog.csdn.net/sdhjob/article/details/38734993 http://www.cnblogs.com/code4app/p/4026665.html ...