题目链接:戳我

题意:将一个长度为n的序列分为k段,使得总价值最大。一段区间的价值表示为区间内不同数字的个数

\(n<=35000,k<=50\)

开始想的转移方程是这个样子的——\(dp[i][j]\)表示前i个,分成j组,最大收益

然后转移方程为\(dp[i][j]=max(dp[i-1][j]+cur,dp[i-1][j-1]+1)\),其中cur表示这个数是否在当前组中出现过,判断可以用set来搞。

但是——不对!!!!

原因是同一种最大收益可能有不同的分组方式,而不同的分组方式显然具有后效性,不能DPqwqwq

所以我们更改DP方程——

\(dp[i][j]=max(dp[k][j-1]+calc(k+1,j))\)

\(dp[i][j]\)表示前i个数分成j份。

但是这个样子的话复杂度是\(O(n^2k)\)的,显然。。。。很凉凉。

于是我们考虑一个神奇的做法——

从j开始遍历(即把j放成外层循环),那么。。。我们遍历i的时候就是从头开始依次加入数,并计算了。而每次加入一个数对于calc的计算来说,就是对它上次出现的位置到现在这个位置都+1.但是注意如果本身就是第一个出现的,那么pre也要改一改,改成自己的。(不过我的代码直接整体前移了一位。)

代码如下:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#define MAXN 350010
using namespace std;
int n,k;
int a[MAXN],dp[MAXN][55],pre[MAXN],f[MAXN],pos[MAXN];
struct Node{int x,l,r,sum,tag;}t[MAXN<<2];
inline int ls(int x){return x<<1;}
inline int rs(int x){return x<<1|1;}
inline void push_up(int x){t[x].sum=max(t[ls(x)].sum,t[rs(x)].sum);}
inline void solve(int x,int k)
{
t[x].sum+=k;
t[x].tag+=k;
}
inline void build(int x,int l,int r)
{
t[x].l=l,t[x].r=r;t[x].tag=0;
if(l==r) {t[x].sum=f[l];return;}
int mid=(l+r)>>1;
build(ls(x),l,mid);
build(rs(x),mid+1,r);
push_up(x);
}
inline void push_down(int x)
{
if(t[x].tag)
{
solve(ls(x),t[x].tag);
solve(rs(x),t[x].tag);
t[x].tag=0;
}
}
inline void update(int x,int ll,int rr)
{
int l=t[x].l,r=t[x].r;
if(ll<=l&&r<=rr) {solve(x,1);return;}
int mid=(l+r)>>1;
push_down(x);
if(ll<=mid) update(ls(x),ll,rr);
if(mid<rr) update(rs(x),ll,rr);
push_up(x);
}
inline int query(int x,int ll,int rr)
{
int l=t[x].l,r=t[x].r;
if(ll<=l&&r<=rr) return t[x].sum;
int mid=(l+r)>>1,cur_ans=0;
push_down(x);
if(ll<=mid) cur_ans=max(cur_ans,query(ls(x),ll,rr));
if(mid<rr) cur_ans=max(cur_ans,query(rs(x),ll,rr));
return cur_ans;
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("ce.in","r",stdin);
#endif
scanf("%d%d",&n,&k);
for(int i=1;i<=n;i++)
{
scanf("%d",&a[i]);
pre[i]=pos[a[i]];
pos[a[i]]=i;
}
//for(int i=1;i<=n;i++) printf("lst[%d]=%d\n",i,pre[i]);
for(int j=1;j<=k;j++)
{
build(1,0,n-1);
for(int i=1;i<=n;i++)
update(1,pre[i],i-1),f[i]=query(1,0,i-1);
}
printf("%d\n",f[n]);
return 0;
}

CF834D The Bakery的更多相关文章

  1. Codeforeces 707B Bakery(BFS)

    B. Bakery time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

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

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

  3. 信号量和PV操作写出Bakery算法的同步程序

    面包店烹制面包及蛋糕,由n个销售员卖出.当有顾客进店购买面包或蛋糕时,应先在取号机上取号,然后等待叫号,若有销售员空闲时便叫下一号,试用信号量和PV操作写出Bakery算法的同步程序. 设计要求 1) ...

  4. 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 ...

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

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

  6. Codeforces Round #426 (Div. 1) B The Bakery (线段树+dp)

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

  7. Codeforces Round #368 (Div. 2) B. Bakery 水题

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

  8. Codeforces 834D - The Bakery(dp+线段树)

    834D - The Bakery 思路:dp[i][j]表示到第j个数为止分成i段的最大总和值. dp[i][j]=max{dp[i-1][x]+c(x+1,j)(i-1≤x≤j-1)},c(x+1 ...

  9. CF833B The Bakery 线段树,DP

    CF833B The Bakery LG传送门 线段树优化DP. 其实这是很久以前就应该做了的一道题,由于颓废一直咕在那里,其实还是挺不错的一道题. 先考虑\(O(n^2k)\)做法:设\(f[i][ ...

随机推荐

  1. 【CentOS 6.5】 Qt Creator 启动失败

    在CentOS 6.5中 点击 [应用程序]->[编程]->Qt Creator , 没有反应,Creator没有启动,转而进入Shell cd /opt/Qt5.2.1/Tools/Qt ...

  2. 现象级AR营销助力“口碑双十二”,蚂蚁特工在全国数万商户掀起“AR捉四宝”

    领取阅读奖励金 今年双十二,全国人民吃喝玩乐放飞自我,嗨出了新纪元.除了见证你国人民的财力,这个“双十二”还诞生了教科书级的“AR营销”.无论是在口碑商户门口,还是在各大购物广场,都能看到举着手机,正 ...

  3. CDN理解<转>

    CDN则是更高级的手段.CDN到底如何工作的呢,让我们来大概了解一下! CDN的基础百科资料也很多了,我也稍等提一下.CDN,Content Distribute Network,即:内容分发网络. ...

  4. LDa 通俗理解

    LDA理解以及源码分析(一) http://blog.csdn.net/pirage/article/details/50239125 LDA在主题建模中的应用,需要知道以下几点: 文档集中的word ...

  5. 手工kill掉VNC进程的故障处理

    1.模拟Kill掉已经启动的VNC服务 1)启动桌面1的服务 [root@testdb ~]# vncserver :1 New 'testdb:1 (root)' desktop is testdb ...

  6. A survey of best practices for RNA-seq data analysis RNA-seq数据分析指南

    A survey of best practices for RNA-seq data analysis RNA-seq数据分析指南 内容 前言 各位同学/老师,大家好,现在由我给大家讲讲我的文献阅读 ...

  7. dedecms导出csv文件

    1.mshd_orderlist.tpl <form id="frm" method="GET" action="mshd_orderlist. ...

  8. file_get_contents()

    file_get_contents()类似于curl接口调用

  9. 我所理解的 PHP Trait

    Trait 是从 PHP 5.4 加入的一种细粒度代码复用的语法.以下是官方手册对 Trait 的描述: Trait 是为类似 PHP 的单继承语言而准备的一种代码复用机制.Trait 为了减少单继承 ...

  10. CodeForces 518A Vitaly and Strings (水题,字符串)

    题意:给定两个相同长度的字符串,让你找出一个字符串,字典序在两都之间. 析:这个题当时WA了好多次,后来才发现是这么水,我们只要把 s 串加上,然后和算数一样,该进位进位,然后再和 t 比较就行. 代 ...