题目链接: http://codeforces.com/contest/834/problem/D

题意: 每个数字代表一种颜色, 一个区间的美丽度为其中颜色的种数, 给出一个有 n 个元素的数组, 问将其分成 k 个区间, 问 k 个区间的美丽度和最大为多少 .

思路: dp + 线段树区间更新, 区间最值

用 dp[i][j] 存储前 j 个元素分成 i 个区间的最大美丽度和为多少, 那么动态转移方程式为:

dp[i][j] = max(dp[i - 1][k] + gel(k + 1, n)), 其中 i <= k <= n, gel(k + 1, n) 表示区间 [k + 1, n] 的美丽度为多少 .

可以用线段树来维护 dp[i -1][k] + gel(k + 1, n) 的值, 这部分和 http://www.cnblogs.com/geloutingyu/p/7298049.html里面的线段树用法是一样的. 建树时将 sum 初始化为上一轮 dp 的结果. 再遍历 [i, m] 并将 dp 结果记录一下即可.

代码:

 #include <iostream>
#include <stdio.h>
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
using namespace std; const int MAXN = 4e4 + ;
int pre[MAXN], last[MAXN], a[MAXN];
int dp[ + ][MAXN], sum[MAXN << ], lazy[MAXN << ]; void push_up(int rt){
sum[rt] = max(sum[rt << ], sum[rt << | ]);
} void push_down(int rt){
if(lazy[rt]){
sum[rt << ] += lazy[rt];
sum[rt << | ] += lazy[rt];
lazy[rt << ] += lazy[rt];
lazy[rt << | ] += lazy[rt];
lazy[rt] = ;
}
} void build(int l, int r, int rt, int k){
lazy[rt] = ;
if(l == r){
sum[rt] = dp[k][l - ];//注意sum初始化为上一轮的dp结果,更新gel(l,m)时只能与dp[i-1][l-1]匹配,所以这里的l也要减一
return;
}
int mid = (l + r) >> ;
build(lson, k);
build(rson, k);
push_up(rt);
} void update(int L, int R, int value, int l, int r, int rt){
if(L <= l && R >= r){
lazy[rt] += value;
sum[rt] += value;
return;
}
push_down(rt);
int mid = (l + r) >> ;
if(L <= mid) update(L, R, value, lson);
if(R > mid) update(L, R, value, rson);
push_up(rt);
} int query(int L, int R, int l, int r, int rt){
if(L <= l && R >= r) return sum[rt];
push_down(rt);
int cnt = ;
int mid = (l + r) >> ;
if(L <= mid) cnt = max(cnt, query(L, R, lson));
if(R > mid) cnt = max(cnt, query(L, R, rson));
return cnt;
} int main(void){
int n, k;
scanf("%d%d", &n, &k);
for(int i = ; i <= n; i++){
scanf("%d", &a[i]);
pre[i] = last[a[i]];
last[a[i]] = i;
}
for(int i = ; i <= k; i++){
build(, n, , i - );
for(int j = i; j <= n; j++){
update(pre[j] + , j, , , n, );
dp[i][j] = query(, j, , n, );
}
}
printf("%d\n", dp[k][n]);
return ;
}

cf834D(dp+线段树区间最值,区间更新)的更多相关文章

  1. HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧)

    HUD.2795 Billboard ( 线段树 区间最值 单点更新 单点查询 建树技巧) 题意分析 题目大意:一个h*w的公告牌,要在其上贴公告. 输入的是1*wi的w值,这些是公告的尺寸. 贴公告 ...

  2. 线段树&&线段树的创建线段树的查询&&单节点更新&&区间更新

    目录 线段树 什么是线段树? 线段树的创建 线段树的查询 单节点更新 区间更新 未完待续 线段树 实现问题:常用于求数组区间最小值 时间复杂度:(1).建树复杂度:nlogn.(2).线段树算法复杂度 ...

  3. kb-07线段树-12--二分查找区间边界

    /* hdu4614 本题刚开始想能不能记录该区间最前面开始的点,最后面的点,区间空的数量:但是病不行 然后线段树的本质是区间操作,所以!这题主要就是区间的空的全放满,只要定出区间的边界就好办了: 这 ...

  4. POJ 3468 A Simple Problem with Integers(线段树 成段增减+区间求和)

    A Simple Problem with Integers [题目链接]A Simple Problem with Integers [题目类型]线段树 成段增减+区间求和 &题解: 线段树 ...

  5. hdu-1754 I Hate It【线段树】(求区间最大值)

    <题目链接> I Hate It Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  6. ZOJ 3349 Special Subsequence 简单DP + 线段树

    同 HDU 2836 只不过改成了求最长子串. DP+线段树单点修改+区间查最值. #include <cstdio> #include <cstring> #include ...

  7. hdu3698 Let the light guide us dp+线段树优化

    http://acm.hdu.edu.cn/showproblem.php?pid=3698 Let the light guide us Time Limit: 5000/2000 MS (Java ...

  8. Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树)

    Codeforces Round #620 F2. Animal Observation (hard version) (dp + 线段树) 题目链接 题意 给定一个nm的矩阵,每行取2k的矩阵,求总 ...

  9. CodeForces834D DP + 线段树

    http://codeforces.com/problemset/problem/834/D 将一个长度为n的序列分为k段 使得总价值最大一段区间的价值表示为区间内不同数字的个数 n<=3500 ...

随机推荐

  1. Appium-appium日志分析

    查看日志是很重要的一部分,我们在编辑器上测试代码时可以直接进行调试,但持续集成时程序自动运行,如果出现bug,只能通过日志来定位代码位置.appium日志主要分为三部分. 1. 准备阶段,包含了app ...

  2. http接口测试框架-python

    简单分解一下 接口测试框架设计: 主入口 -> 遍历接口/用例 -> 发送请求+接收响应 ->结果的对比 -> 生成报告 ->发送email 分成几大类:主入口的py文件 ...

  3. Java_异常_02_java.lang.NoClassDefFoundError: org/apache/log4j/Level

    总结:解析Json时,除了要导入json-lib-2.2-jdk15.jar外,还要导入: commons-beanutils.jar, commons-httpclient.jar, commons ...

  4. Git之Eclipse提交项目到Github并实现多人协作

    一.Eclipece提交项目到Github 见  eclipse提交项目到github 二.利用github组织实现多人协作 1.新建组织: New organization

  5. css 一些技巧

    记录一下,某些实用的css: 1.以下代码将会为普通屏幕使用 image.png,为高分屏使用 image_2x.png,如果更高的分辨率则使用 image_print.png. div { back ...

  6. QToolBox

    QToolBox类似与以前qq好友分组的那种控件.每个分组是一个Item. 一.添加分组: 其中每个分组是通过一下函数添加的: int addItem(QWidget * w, const QIcon ...

  7. QMainFrame类

    一.简介: 1.QMainFrame类提供了应用程序的主窗口,因为它可以添加菜单.工具条.状态栏和停靠窗口,同时也支持单文档窗口和多文档窗口,这是它和其他窗口不一样的地方. 2.QMainFrame窗 ...

  8. hdu-1286 找新朋友(欧拉函数,水题)

    题目链接: 找新朋友 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total ...

  9. linux命令学习笔记(39):grep 命令

    Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹 配的行打印出来. grep全称是Global Regular Expression Print,表示全局正则表 ...

  10. 【集成学习】lightgbm参数介绍(sklearn)

    #  XGBoost和LightGBM部分参数对比表: lightgbm.sklearn参数介绍(官网)