题意:

  给定一个序列,你要将其分为k段,总的代价为每段的权值之和,求最小代价。

  定义一段序列的权值为$\sum_{i = 1}^{n}{\binom{cnt_{i}}{2}}$,其中$cnt_{i}$表示当前这段序列中数字大小为i的数的个数。

题解:

  先考虑暴力DP, f[i][j]表示DP到i位,分为j段的最小代价。

  则$f[i][j] = min(f[l - 1][j] + sum[l][i])$,其中sum[l][i]表示区间[l, i]分成一段的代价。

  然后可以发现,这是具有决策单调性的,简易证明:

    首先设l < j < i.

    假设f[i][t]从f[j - 1][t - 1]转移而来,则有$f[j - 1][t - 1] + w[j][i] < f[l - 1][t - 1] + w[l][i]$.

    现在考虑i + 1的情况,观察到$\binom{cnt_{i}}{2}$的式子经过化简后恰好可以表示0 ~ n - 1这个等差数列的求和公式,因此w[j][i]可以O(1)的转移到w[j][i + 1],即w[j][i + 1] = w[j][i] + sum[j][i];.sum[j][i]表示这个区间内某个颜色的数量(懒得再打一维了,这个理解一下就好,只是这么表示而已)

    所以f[i + 1][t] = min(f[j - 1][t - 1] + w[j][i] + sum[j][i], f[l - 1][t - 1] + w[l][i] + sum[l][i]);//可以发现,由于$l < j$,所以$sum[l][i] >= sum[j][i]$,而式子的另一部分,也就是和f[i][t]相同的部分也是左边小于右边,因此j一定比l优。

   因此可以利用决策单调性来优化DP,因为无法O(1)得知w[i][j]的值,因此无法用二分单调栈来进行优化,于是我们考虑分治。

   不知道如何用分治优化决策单调性戳:决策单调性优化DP

  然后注意到对于这题而言,暴力转移的复杂度还是太高了,于是考虑利用以下之前已有的信息,设当前已经被求出权值的区间为[ll, rr],权值为rnt.

  那么每次转移的时候暴力将这个区间转移至当前需要的区间,于是就可以做到重复利用之前已经求出的信息。   

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 101000
#define LL long long
#define inf 1e18 int n, k, now, ll, rr;
int s[AC], sum[AC];
LL f[AC][], rnt; inline int read()
{
int x = ;char c = getchar();
while(c > '' || c < '') c = getchar();
while(c >= '' && c <= '') x = x * + c - '', c = getchar();
return x;
} void pre()
{
n = read(), k = read();
for(R i = ; i <= n; i ++) s[i] = read();
} void cal(int l, int r)
{
while(rr < r) rnt += sum[s[++ rr]] ++;
while(rr > r) rnt -= -- sum[s[rr --]];
while(ll > l) rnt += sum[s[-- ll]] ++;
while(ll < l) rnt -= -- sum[s[ll ++]];
} void solve(int l, int r, int kl, int kr)//当前区间[l, r],决策点区间[kl, kr]
{
if(l > r) return ;
int mid = (l + r) >> , k = -, b = min(mid, kr);
for(R i = kl; i <= b; i ++)//枚举当前段开头
{
cal(i, mid);
if(rnt + f[i - ][now - ] < f[mid][now])
f[mid][now] = rnt + f[i - ][now - ], k = i;
}
solve(l, mid - , kl, k), solve(mid + , r, k, kr);
} void work()
{
for(R i = ; i <= n; i ++)
for(R j = ; j <= k; j ++) f[i][j] = inf;
ll = , rr = n;
for(R i = ; i <= n; i ++) rnt += sum[s[i]] ++;
for(now = ; now <= k; now ++) solve(, n, , n);//分层做k次
printf("%lld\n", f[n][k]);
} int main()
{
freopen("in.in", "r", stdin);
pre();
work();
fclose(stdin);
return ;
}

CF868F Yet Another Minimization Problem 分治决策单调性优化DP的更多相关文章

  1. Codeforces 868F. Yet Another Minimization Problem【决策单调性优化DP】【分治】【莫队】

    LINK 题目大意 给你一个序列分成k段 每一段的代价是满足\((a_i=a_j)\)的无序数对\((i,j)\)的个数 求最小的代价 思路 首先有一个暴力dp的思路是\(dp_{i,k}=min(d ...

  2. CF868F Yet Another Minimization Problem(决策单调性)

    题目描述:给定一个序列,要把它分成k个子序列.每个子序列的费用是其中相同元素的对数.求所有子序列的费用之和的最小值. 输入格式:第一行输入n(序列长度)和k(需分子序列段数).下一行有n个数,序列的每 ...

  3. 决策单调性优化dp 专题练习

    决策单调性优化dp 专题练习 优化方法总结 一.斜率优化 对于形如 \(dp[i]=dp[j]+(i-j)*(i-j)\)类型的转移方程,维护一个上凸包或者下凸包,找到切点快速求解 技法: 1.单调队 ...

  4. Lightning Conductor 洛谷P3515 决策单调性优化DP

    遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...

  5. 2018.09.28 bzoj1563: [NOI2009]诗人小G(决策单调性优化dp)

    传送门 决策单调性优化dp板子题. 感觉队列的写法比栈好写. 所谓决策单调性优化就是每次状态转移的决策都是在向前单调递增的. 所以我们用一个记录三元组(l,r,id)(l,r,id)(l,r,id)的 ...

  6. [BZOJ4850][JSOI2016]灯塔(分块/决策单调性优化DP)

    第一种方法是决策单调性优化DP. 决策单调性是指,设i>j,若在某个位置x(x>i)上,决策i比决策j优,那么在x以后的位置上i都一定比j优. 根号函数是一个典型的具有决策单调性的函数,由 ...

  7. BZOJ2216 Poi2011 Lightning Conductor 【决策单调性优化DP】

    Description 已知一个长度为n的序列a1,a2,...,an. 对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt( ...

  8. 算法学习——决策单调性优化DP

    update in 2019.1.21 优化了一下文中年代久远的代码 的格式…… 什么是决策单调性? 在满足决策单调性的情况下,通常决策点会形如1111112222224444445555588888 ...

  9. BZOJ4899: 记忆的轮廓【概率期望DP】【决策单调性优化DP】

    Description 通往贤者之塔的路上,有许多的危机. 我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增, 在[1,n]中,一共有n个节点.我 ...

随机推荐

  1. Linux安装Apache常见报错(一)

    启动Apache提示报错:Could not reliably determine the server's fully qualified domain name, using localhost, ...

  2. 多线程系列之四:Guarded Suspension 模式

    一,什么是Guarded Suspension模式如果执行现在的处理会造成问题,就让执行处理的线程等待.这种模式通过让线程等待来保证实例的安全性 二,实现一个简单的线程间通信的例子 一个线程(Clie ...

  3. 【问题解决方案】Git bash进入多层子目录问题(通配符问题留坑)

    cd进入指定路径下:cd 斜杠 斜杠 方法一: 1- 撇丿,不是"那",盘符前面要加上 / (d盘前面也加,不加也行) 2- 路径名不区分大小写 3- 不用空格 4- 如果目录名中 ...

  4. 自签名证书 nginx tomcat

    给Nginx配置一个自签名的SSL证书 - 廖雪峰的官方网站 https://www.liaoxuefeng.com/article/0014189023237367e8d42829de24b6eaf ...

  5. Tomcat集成Memcached Session Manager方案

    http://repo1.maven.org/maven2/de/javakaffee/msm/memcached-session-manager/2.3.2/memcached-session-ma ...

  6. winform自定义控件开发

    1.添加控件属性 //添加私有的控件属性 private string djm;//单据名 //添加属性描述 [Browsable(true)] [Description("djm" ...

  7. js 精确验证身份证(地址编码、出生日期、校验位验证)

    //身份证号合法性验证 //支持15位和18位身份证号 //支持地址编码.出生日期.校验位验证 function IdentityCodeValid(code) { ::::::::::::::::: ...

  8. [转帖]linux tree命令--显示目录的树形结构

    linux tree命令--显示目录的树形结构    版权声明:iamqilei@qq.com https://blog.csdn.net/u011729865/article/details/533 ...

  9. Socket用线程池处理服务

    while(true){ try{ Socket clientSocket = serverSocket.accept(); new Thread(new HandlerThread(clientSo ...

  10. centos7根分区扩容(亲测有效)

    root@haojftest:~# df -h 文件系统 容量 已用 可用 已用% 挂载点 /dev/mapper/centos_test2-root 28G 14G 15G % / devtmpfs ...