题目链接: 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. mysql一些操作

    1.产生随机数 SELECT rand();   随机一个0-1的随机数. 2.截取小数点后 SELECT FORMAT(RAND()*10000,2); 在返回 1,306.47 数据中“,” SE ...

  2. node.js+express验证码的实现

    安装ccap库 npm install ccap var ccap = require(); var captcha = ccap({ width:190, height:50, offset:30, ...

  3. Python基础-list,tuple,dict,set常用方法及区别

    1,列表list 列表定义方式 lis1=[1,2,3,4]#一维数组 lis2=[1,2,3,[4,5,6]]#二维数组 依次多有多维数据,套几层就是几维数组 列表的取值可以通过下标来,下标都是从0 ...

  4. 查看字符串的编码chardet

    The Universal Character Encoding Detector chardet.detect("str") 返回:{‘confidence’:1.0,'enco ...

  5. OpenCV - Android Studio 中集成Opencv环境(包含opencv_contrib部分)

    我在上一篇博客中说到了在Android中集成OpenCV,但是那个版本的OpenCV是没有SIFT和SURF算法的,因为这些算法是受专利保护的,所以并没有被包含在预编译库中,所以如果想要使用SIFT和 ...

  6. 【LeetCode】023. Merge k Sorted Lists

    Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity. 题 ...

  7. rufus-scheduler定时任务示例代码

    require 'rubygems' require 'rufus/scheduler' scheduler = Rufus::Scheduler.start_new scheduler.in '20 ...

  8. TS学习之泛型

    可以使用泛型来创建可重用的组件,一个组件可以支持多种类型的数据 不适用泛型的函数 function myfn(args: number): number { return args; } functi ...

  9. MS SQL update set select

    有张表a,已经有数据 再有张表b,也已查询出数据 两张表有外键关联 需求如下: 更新表a中的某个字段,这个字段要加上(都是int型的数据)对应表b中的数据作为更新的最终数据 )) from #libL ...

  10. 在Action获取Scope对象

    引言:在前面的Action操作中,关键就是Action中的exectue方法,但是此方法并没有request.session.application等对象作为参数,自然就不能利用这些对象来操作.下面我 ...