cf868F. Yet Another Minimization Problem(决策单调性 分治dp)
题意
给定一个长度为\(n\)的序列。你需要将它分为\(m\)段,每一段的代价为这一段内相同的数的对数,最小化代价总和。
\(n<=10^5,m<=20\)
Sol
看完题解之后的感受:

首先列出裸的dp方程,\(f[i][j]\)表示前\(i\)个位置,切了\(j\)次,转移的时候枚举上一次且在了哪儿
\(f[i][j] = max(f[k][j - 1] + w(k, i))\)
\(w(k, i)\)表示\([k, i]\)内相同的数的对数。。
然后sb的我以为拿个单调队列维护一下就完了结果发现转移是\(O(n)\)的??
标算真神仙Orz
因为转移不是\(O(n)\)的,所以我们可以分治的去做
假设当前要求的区间为\([l, r]\),可以从\([L, R]\)转移而来,\(mid = (l + r)/ 2\)的决策点为\(p\)
那么\([l, mid - 1]\)的转移区间一定在\([L, p]\),\([mid+1, r]\)的转移区间一定是\([p, R]\),递归的做即可
画出图来应该是这样的
求解区间:\(|\gets\)预处理\(\to |\) \(l\frac{\qquad\qquad\qquad\downarrow^{mid}\qquad\qquad\qquad}{}r\)
决策区间:\(L\frac{\qquad\qquad\qquad\downarrow^{p}\qquad\qquad\qquad}{}R\)
转移的时候需要记录每个数的出现次数,每次转移时\(O(1)\)的
总的时间复杂度为:\(O(nlognk)\)
#include<bits/stdc++.h>
#define LL long long
using namespace std;
const int MAXN = 1e5 + 10;
inline int read() {
int x = 0, f = 1; char c = getchar();
while(c < '0' || c > '9') {if(c == '-') f = -1; c = getchar();}
while(c >= '0' && c <= '9') x = x * 10 + c - '0', c = getchar();
return x * f;
}
int N, K, a[MAXN], b[MAXN];
LL f[MAXN], g[MAXN];
void solve(int l, int r, int L, int R, LL w) {
if(l > r) return ;
int mid = l + r >> 1, p = min(mid, R), k = 0;
for(int i = l; i <= mid; i++) w += b[a[i]]++;
for(int i = L; i <= p; i++) w -= --b[a[i]], f[mid] > g[i] + w ? f[mid] = g[i] + w, k = i : 0;
for(int i = l; i <= mid; i++) w -= --b[a[i]];
for(int i = L; i <= p; i++) w += b[a[i]]++;
solve(l, mid - 1, L, k, w);
for(int i = L; i < k; i++) w -= --b[a[i]];
for(int i = l; i <= mid; i++) w += b[a[i]]++;
solve(mid + 1, r, k, R, w);
for(int i = l; i <= mid; i++) --b[a[i]];
for(int i = L; i < k; i++) ++b[a[i]];
}
main() {
N = read(); K = read();
for(int i = 1; i <= N; i++) a[i] = read(), g[i] = g[i - 1] + b[a[i]]++; memset(b, 0, sizeof(b));
while(K--) {memset(f, 0x7f, sizeof(f)); solve(1, N, 1, N, 0); swap(f, g);}
cout << f[N];
}
cf868F. Yet Another Minimization Problem(决策单调性 分治dp)的更多相关文章
- CodeForces 868F Yet Another Minimization Problem(决策单调性优化 + 分治)
题意 给定一个序列 \(\{a_1, a_2, \cdots, a_n\}\),要把它分成恰好 \(k\) 个连续子序列. 每个连续子序列的费用是其中相同元素的对数,求所有划分中的费用之和的最小值. ...
- Codeforces 868F Yet Another Minimization Problem 决策单调性 (看题解)
Yet Another Minimization Problem dp方程我们很容易能得出, f[ i ] = min(g[ j ] + w( j + 1, i )). 然后感觉就根本不能优化. 然后 ...
- [BZOJ5125]小Q的书架(决策单调性+分治DP+树状数组)
显然有决策单调性,但由于逆序对不容易计算,考虑分治DP. solve(k,x,y,l,r)表示当前需要选k段,待更新的位置为[l,r],这些位置的可能决策点区间为[x,y].暴力计算出(l+r)/2的 ...
- CF868F Yet Another Minimization Problem 分治决策单调性优化DP
题意: 给定一个序列,你要将其分为k段,总的代价为每段的权值之和,求最小代价. 定义一段序列的权值为$\sum_{i = 1}^{n}{\binom{cnt_{i}}{2}}$,其中$cnt_{i}$ ...
- CF868 F. Yet Another Minimization Problem 决策单调优化 分治
目录 题目链接 题解 代码 题目链接 CF868F. Yet Another Minimization Problem 题解 \(f_{i,j}=\min\limits_{k=1}^{i}\{f_{k ...
- P2877 [USACO07JAN]牛校Cow School(01分数规划+决策单调性分治)
P2877 [USACO07JAN]牛校Cow School 01分数规划是啥(转) 决策单调性分治,可以解决(不限于)一些你知道要用斜率优化却不会写的问题 怎么证明?可以暴力打表 我们用$ask(l ...
- 4951: [Wf2017]Money for Nothing 决策单调性 分治
Bzoj4951:决策单调性 分治 国际惯例题面:一句话题面:供应商出货日期为Ei,售价为Pi:用户收购截止日期为Si,收购价格为Gi.我们要求max((Si-Ej)*(Gi-Pj)).显然如果我们把 ...
- [NAIPC2016]Jewel Thief(决策单调性+分治)
[NAIPC2016]Jewel Thief(决策单调性+分治) 题面 原题提交地址(题目编号H) 原题面下载地址 有\(n\)个物品,每个物品有一个体积\(w_i\)和价值\(v_i\),现在要求对 ...
- P3515 [POI2011]Lightning Conductor(决策单调性分治)
P3515 [POI2011]Lightning Conductor 式子可转化为:$p>=a_j-a_i+sqrt(i-j) (j<i)$ $j>i$的情况,把上式翻转即可得到 下 ...
随机推荐
- flask + pymysql操作Mysql数据库
安装flask-sqlalchemy.pymysql模块 pip install flask-sqlalchemy pymysql ### Flask-SQLAlchemy的介绍 1. ORM:Obj ...
- JS字符串替换(jQuery)
①自己封装的一个方法String.format String.format = function() { var s = arguments[0]; for (var i = 0; i < ar ...
- P2723 丑数 Humble Numbers
题意:给你k个质数,定义丑数集合为k个质数随机(1--k)个相乘得到的数 求第n小的丑数 暴力...貌似不太可行,(把所有大量丑数求出来,sort QAQ) 可以想到,对于第i个丑数f[i],它一 ...
- CF959C Mahmoud and Ehab and the wrong algorithm 构造
Mahmoud was trying to solve the vertex cover problem on trees. The problem statement is: Given an un ...
- shell脚本安装jdk
#!/bin/bash BASE_SERVER=192.168.1.11 yum install -y wget wget $BASE_SERVER/soft-all/jdk-7u45-linux-x ...
- Qt 学习之路 2(10):对象模型
Home / Qt 学习之路 2 / Qt 学习之路 2(10):对象模型 Qt 学习之路 2(10):对象模型 豆子 2012年9月2日 Qt 学习之路 2 45条评论 标准 C++ 对象模 ...
- 说Gradle
说Gradle 刚开始认识Gradle这个名词是在蘑菇街的一场 交流会上,当时只是一个概念:第二面,是试图下载编译spring源码的时候:第三面,就是我司较真的安卓主程,有一天兴高彩烈的跟我说,我 ...
- CSS(十二).transition的应用之CSS中心扩散
实现 css中心向两边扩散的两个核心 1.hover 之前的 垂直居中 2.文字置于最顶层 顺道来讲讲hover 伪元素是不支持 hover 的,不过我们可以给普通的 tag 标签添加 hover 以 ...
- day_09 函数及参数
1.定义:把功能封装起来,方便下次直接调用 2.语法:def 关键词开头,空格之后接函数名称和圆括号(). def 函数名(形参) 函数体 3.参数:圆括号用来接收参数.若传入多个参数,参数之间用逗号 ...
- opencv-将分离合并图像(Red通道>125置255<=置0)
#include <iostream> #include <opencv2/opencv.hpp> #include "opencv2/imgproc/imgproc ...