题

  OwO http://codeforces.com/contest/833/problem/B

解

  首先读入的时候把数据读入到2 ~ n+1的位置(因为线段树处理不到0,所以后移了一格)

  dp[i][j]代表处理到第i个位置为止,分j段能得到的最大值

  lst[i]记录第与第i个蛋糕一样的蛋糕出现的上一个位置

  则,显然dp[i][j]=min(dp[i-t][j-1]+(从i-t+1到i位置的不同种类的蛋糕个数))

  记对每一段的值有贡献的点为同一段每种类型蛋糕最左边的点(比如其中一段AAFBCCDBAB,那么对这一段有贡献的B为F后面的那个B,因为他最先出现)

  那么可以从小到大枚举k

  每一次枚举的时候根据k-1时的dp值建一个线段树,从左往右遍历蛋糕数组,扫到第i个蛋糕的时候,线段树上第t个点表示的是上一段的右端点取t时(即这一段起点取t+1)dp[i][k]的取值,那么显然这是一个区间最大值得线段树

  维护的话,扫到第i个蛋糕的时候,线段树上(lst[i],i-1)区间的值+1,因为第k-1个区间的右端点取t取(lst[i],i-1)上的点时(即第k个区间为(t+1,i),包括了第i个蛋糕,而且第i个蛋糕为该区间第一个该种蛋糕),cake[i]种类对第k个区间有贡献

  查询的话,扫到第i个蛋糕的时候,查询第k-1段右节点可以选的那一段的就可以了

  

#include <iostream>
#include <cstring>
#include <cstdio>
#include <algorithm>
#include <cmath> using namespace std; const int M=5e4; int dp[M][60],nowk;
int tree[M*3],tag[M*3]; void build(int rt,int li,int ri)
{
tag[rt]=0;
if(li==ri)
{
tree[rt]=dp[li][nowk];
return ;
}
int mid=(li+ri)>>1,lc=(rt<<1),rc=(rt<<1)+1;
build(lc,li,mid);
build(rc,mid+1,ri);
tree[rt]=max(tree[lc],tree[rc]);
} void pushdown(int rt,int li,int ri)
{
if(li==ri)
{
tag[rt]=0;
return ;
}
int mid=(li+ri)>>1,lc=(rt<<1),rc=(rt<<1)+1;
tree[lc]+=tag[rt];
tree[rc]+=tag[rt];
tag[lc]+=tag[rt];
tag[rc]+=tag[rt];
tag[rt]=0;
} void update(int rt,int li,int ri,int lq,int rq,int val) //add
{
if(lq<=li && ri<=rq)
{
tag[rt]+=val;
tree[rt]+=val;
return ;
}
int mid=(li+ri)>>1,lc=(rt<<1),rc=(rt<<1)+1;
if(tag[rt])
pushdown(rt,li,ri);
if(mid>=lq)
update(lc,li,mid,lq,rq,val);
if(mid+1<=rq)
update(rc,mid+1,ri,lq,rq,val);
tree[rt]=max(tree[lc],tree[rc]);
} int query(int rt,int li,int ri,int lq,int rq) //get max
{
int ret=-1e9-7;
if(lq<=li && ri<=rq)
return tree[rt];
int mid=(li+ri)>>1,lc=(rt<<1),rc=(rt<<1)+1;
if(tag[rt])
pushdown(rt,li,ri);
if(mid>=lq)
ret=max(ret,query(lc,li,mid,lq,rq));
if(mid+1<=rq)
ret=max(ret,query(rc,mid+1,ri,lq,rq));
return ret;
} int n,k;
int cake[M];
int lst[M],tmp[M];
int ans; void init()
{
int i,j;
for(i=1;i<=n+1;i++)
tmp[i]=1;
for(i=2;i<=n+1;i++)
{
lst[i]=tmp[cake[i]];
tmp[cake[i]]=i;
}
ans=0;
memset(dp,0,sizeof(dp));
} int main()
{
int i,j,tmp;
scanf("%d%d",&n,&k);
for(i=2;i<=n+1;i++)
scanf("%d",&cake[i]);
init();
n++;
for(i=1;i<=k;i++)
{
nowk=i-1;
build(1,1,n);
for(j=i+1;j<=n;j++)
{
update(1,1,n,lst[j],j-1,1);
tmp=query(1,1,n,i,j-1);
// cout<<tmp<<endl;
dp[j][i]=max(dp[j][i],tmp);
}
}
ans=dp[n][k];
cout<<ans<<endl;
return 0;
}

  

Codeforces 833B / B34D The Bakery的更多相关文章

  1. codeforces 834 D. The Bakery

    codeforces 834 D. The Bakery(dp + 线段树优化) 题意: 给一个长度为n的序列分成k段,每段的值为这一段不同数字的个数,最大化划分k端的值 $n <= 35000 ...

  2. Codeforces 833B The Bakery dp线段树

    B. The Bakery time limit per test 2.5 seconds memory limit per test 256 megabytes input standard inp ...

  3. Codeforces 833B The Bakery(主席树 + 决策单调性优化DP)

    题目链接 The Bakery 题目大意:目标是把$n$个数分成$k$组,每个组的值为这个组内不同的数的个数,求$k$个组的值的和的最大值. 题目分析: 这道题我的解法可能和大众解法不太一样……我用主 ...

  4. CodeForces - 833B The Bakery

    题解: 线段树经典应用 首先暴力$f[i][j]$表示考虑前i位分成j段的最大值 转移$f[k][j-1]+cost(k+1,i)$枚举k转移 不同数的经典套路就是从它到它前驱这一段 于是维护每个数前 ...

  5. Codeforces.833B.The Bakery(线段树 DP)

    题目链接 \(Description\) 有n个数,将其分为k段,每段的值为这一段的总共数字种类,问最大总值是多少 \(Solution\) DP,用\(f[i][j]\)表示当前在i 分成了j份(第 ...

  6. Codeforces 833B 题解(DP+线段树)

    题面 传送门:http://codeforces.com/problemset/problem/833/B B. The Bakery time limit per test2.5 seconds m ...

  7. Codeforces Round #368 (Div. 2) B. Bakery (模拟)

    Bakery 题目链接: http://codeforces.com/contest/707/problem/B Description Masha wants to open her own bak ...

  8. Codeforces 834D The Bakery【dp+线段树维护+lazy】

    D. The Bakery time limit per test:2.5 seconds memory limit per test:256 megabytes input:standard inp ...

  9. Codeforces 834D The Bakery - 动态规划 - 线段树

    Some time ago Slastyona the Sweetmaid decided to open her own bakery! She bought required ingredient ...

随机推荐

  1. Android笔记01--手机振动

    一.android任务栈  不懂? 栈:先进后出 队列:先进先出 任务栈Task中:打开一个Activity叫进栈 关闭一个activit出栈 任务栈是用来维护Activity的.是用来维护用户的操作 ...

  2. Oracle系统权限与对象权限

    oracle权限分为: 系统权限: 允许用户执行特定的数据库动作,如创建表.创建索引.连接实例等. 对象权限: 允许用户操纵一些特定的对象,如读取视图,可更新某些列.执行存储过程等. 系统权限 超过一 ...

  3. Spring系列四:Bean Scopes作用域

    等闲识得东风面,万紫千红总是春. 概述 在Spring框架中,我们可以在六个内置的spring bean作用域中创建bean,还可以定义bean范围.在这六个范围中,只有在使用支持Web的applic ...

  4. Spring4学习回顾之路07- 通过工厂方法配置Bean

    一:通过静态工厂配置Bean 建立Student.java package com.lql.srping04; /** * @author: lql * @date: 2019.10.28 * Des ...

  5. python设计购物车

    设计购物车 一需求: 1.启动程序后,输入用户名密码后,如果是第一次登录,让用户输入工资,然后打印商品列表 2.允许用户根据商品编号购买商品 3.用户选择商品后,检测余额是否够,够就直接扣款,不够就提 ...

  6. hdu 1969 pie 卡精度的二分

    Pie Time Limit: 5000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Submiss ...

  7. JS基础_嵌套的for循环

    <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...

  8. git 的用法和命令

    学无止境,精益求精! 十年河东,十年河西,莫欺少年穷! 学历代表你的过去,能力代表你的现在,学习代表你的将来! 很久没写博客了,都是工作太忙闹的,索性今儿转发一篇!省的博客园太冷清了... Git图形 ...

  9. Java ArrayList常用接口介绍及示例

    Java List 常用类型 类型 特征 ArrayList 随机访问元素快:中间插入与删除元素较慢:操作不是线程安全的 LinkedList 中间插入与删除操作代价较低,提供优化的顺序访问:随机访问 ...

  10. TVM调试指南

    1. TVM安装 这部分之前就写过,为了方便,这里再复制一遍. 首先下载代码 git clone --recursive https://github.com/dmlc/tvm 这个地方最好使用--r ...