Codeforces 868F. Yet Another Minimization Problem【决策单调性优化DP】【分治】【莫队】
题目大意
给你一个序列分成k段
每一段的代价是满足\((a_i=a_j)\)的无序数对\((i,j)\)的个数
求最小的代价
思路
首先有一个暴力dp的思路是\(dp_{i,k}=min(dp_{j,k}+calc(j+1,i))\)
然后看看怎么优化
证明一下这个DP的决策单调性:
trz说可以冥想一下是对的就可以
所以我就不证了
(其实就是决策点向左移动一定不会更优)
然后就分治记录当前的处理区间和决策区间就可以啦
//Author: dream_maker
#include<bits/stdc++.h>
using namespace std;
//----------------------------------------------
typedef pair<int, int> pi;
typedef long long ll;
typedef double db;
#define fi first
#define se second
#define fu(a, b, c) for (int a = b; a <= c; ++a)
#define fd(a, b, c) for (int a = b; a >= c; --a)
#define fv(a, b) for (int a = 0; a < (signed)b.size(); ++a)
const int INF_of_int = 1e9;
const ll INF_of_ll = 1e18;
template <typename T>
void Read(T &x) {
bool w = 1;x = 0;
char c = getchar();
while (!isdigit(c) && c != '-') c = getchar();
if (c == '-') w = 0, c = getchar();
while (isdigit(c)) {
x = (x<<1) + (x<<3) + c -'0';
c = getchar();
}
if (!w) x = -x;
}
template <typename T>
void Write(T x) {
if (x < 0) {
putchar('-');
x = -x;
}
if (x > 9) Write(x / 10);
putchar(x % 10 + '0');
}
//----------------------------------------------
const int N = 1e5 + 10;
const int M = 23;
int n, m, a[N], cnt[N] = {0};
ll nowl = 1, nowr = 0, res = 0;
ll dp[N][M];
void move_step(int al, int ar) {
while (nowr < ar) {
++nowr;
res += cnt[a[nowr]];
++cnt[a[nowr]];
}
while (nowl > al) {
--nowl;
res += cnt[a[nowl]];
++cnt[a[nowl]];
}
while (nowr > ar) {
--cnt[a[nowr]];
res -= cnt[a[nowr]];
--nowr;
}
while (nowl < al) {
--cnt[a[nowl]];
res -= cnt[a[nowl]];
++nowl;
}
}
void solve(int l, int r, int ql, int qr, int k) {
if (l > r) return;
int mid = (l + r) >> 1, pos = mid;
fu(i, ql, min(qr, mid - 1)) {
move_step(i + 1, mid);
if (dp[i][k - 1] + res < dp[mid][k]) {
dp[mid][k] = dp[i][k - 1] + res;
pos = i;
}
}
solve(l, mid - 1, ql, pos, k);
solve(mid + 1, r, pos, qr, k);
}
int main() {
#ifdef dream_maker
freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
#endif
Read(n), Read(m);
fu(i, 1, n) Read(a[i]);
fu(i, 1, n)
fu(j, 0, m) dp[i][j] = INF_of_ll;
dp[0][0] = 0;
fu(i, 1, m) solve(1, n, 0, n, i);
Write(dp[n][m]);
return 0;
}
Codeforces 868F. 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 )). 然后感觉就根本不能优化. 然后 ...
- CF868F Yet Another Minimization Problem 分治决策单调性优化DP
题意: 给定一个序列,你要将其分为k段,总的代价为每段的权值之和,求最小代价. 定义一段序列的权值为$\sum_{i = 1}^{n}{\binom{cnt_{i}}{2}}$,其中$cnt_{i}$ ...
- Lightning Conductor 洛谷P3515 决策单调性优化DP
遇见的第一道决策单调性优化DP,虽然看了题解,但是新技能√,很开森. 先%FlashHu大佬,反正我是看了他的题解和精美的配图才明白的,%%%巨佬. 废话不多说,看题: 题目大意 已知一个长度为n的序 ...
- 2018.09.28 bzoj1563: [NOI2009]诗人小G(决策单调性优化dp)
传送门 决策单调性优化dp板子题. 感觉队列的写法比栈好写. 所谓决策单调性优化就是每次状态转移的决策都是在向前单调递增的. 所以我们用一个记录三元组(l,r,id)(l,r,id)(l,r,id)的 ...
- [BZOJ4850][JSOI2016]灯塔(分块/决策单调性优化DP)
第一种方法是决策单调性优化DP. 决策单调性是指,设i>j,若在某个位置x(x>i)上,决策i比决策j优,那么在x以后的位置上i都一定比j优. 根号函数是一个典型的具有决策单调性的函数,由 ...
- BZOJ2216 Poi2011 Lightning Conductor 【决策单调性优化DP】
Description 已知一个长度为n的序列a1,a2,...,an. 对于每个1<=i<=n,找到最小的非负整数p满足 对于任意的j, aj < = ai + p - sqrt( ...
- 决策单调性优化dp 专题练习
决策单调性优化dp 专题练习 优化方法总结 一.斜率优化 对于形如 \(dp[i]=dp[j]+(i-j)*(i-j)\)类型的转移方程,维护一个上凸包或者下凸包,找到切点快速求解 技法: 1.单调队 ...
- 算法学习——决策单调性优化DP
update in 2019.1.21 优化了一下文中年代久远的代码 的格式…… 什么是决策单调性? 在满足决策单调性的情况下,通常决策点会形如1111112222224444445555588888 ...
- BZOJ4899: 记忆的轮廓【概率期望DP】【决策单调性优化DP】
Description 通往贤者之塔的路上,有许多的危机. 我们可以把这个地形看做是一颗树,根节点编号为1,目标节点编号为n,其中1-n的简单路径上,编号依次递增, 在[1,n]中,一共有n个节点.我 ...
随机推荐
- Saltstack数据系统
1.grainsgrains 是在 minion(客户端)启动时收集到的一些信息,比如操作系统类型.网卡ip等.强调是minion启动时收集到的数据,所以如果改了什么硬件啥的,要重启minion才能收 ...
- Java实现最基本的集中排序
排序是一个很重要的概念,现实生活中,我们需要为很多的东西排序.下面我们就介绍几种简单的排序的方法和最基本的思想. 1.冒泡排序:假设一个数组中有10个数字,从左边开始
- 478. Generate Random Point in a Circle
1. 问题 给定一个圆的半径和圆心坐标,生成圆内点的坐标. 2. 思路 简单说 (1)在圆内随机取点不好做,但是如果画出这个圆的外接正方形,在正方形里面采样就好做了. (2)取两个random确定正方 ...
- “System.Runtime.InteropServices.COMException (0x80070422): 无法启动服务”解决方法
应用程序中发生了无法处理的异常.如果单击“退出”,应用程序将立即关闭.无法启动服务,原因可能是已被禁用或其相关联设备没有启动.(异常来自HRESULT:0X80070422).点击详细内容:有关调用实 ...
- STM32 DMA简述
STM32 DMA简述 DMA (Direct Memory Access) 直接内存存储器,在做数据传输时能够大大减轻CPU的负担. DMA的作用 DMA提供了一个关于数据的高数传输通道,这个通道不 ...
- MP3的采样率和比特率
我们听mp3,看电影都会注意到两个参数,常见的有采样率44.1KHz,比特率192Kbps,那么什么是采样率,什么是比特率?他们是什么关系呢?下面就我们就来简单做个解释: 把模拟音频信号转成数字音频信 ...
- stm32 Flash读写独立函数[库函数]
一. stm32的FLASH分为 1.主存储块:用于保存具体的程序代码和用户数据,主存储块是以页为单位划分的, 一页大小为1KB.范围为从地址0x08000000开始的128KB内. 2.信息块 ...
- Linux点亮一个灯
一 文件及其驱动程序 1.解压linux 压缩包 使用命令: tar xzvf linux-3.0.8-20140925.tgz ( tar xvf ------.tar tar xzvf------ ...
- 关于函数strtok和strtok_r的使用要点和实现原理(二)【转】
本文转载自:http://astute11.blog.51cto.com/4404646/1334199 (一)中已经介绍了使用strtok函数的一些注意事项,本篇将介绍strtok的一个应用并引出s ...
- linux下如何退出tmux和重新进入tmux
1.退出(detach)当前tmux ctrl+d 2.重新进入tmux tmux attach -t <target-session> 如:当前有很多session,那么选择哪一个呢? ...