CF 868 F. Yet Another Minimization Problem
F. Yet Another Minimization Problem
http://codeforces.com/contest/868/problem/F
题意:
给定一个长度为n的序列。你需要将它分为m段,每一段的代价为这一段内相同的数的对数,最小化代价总和。 n<=100000,m<=20。
分析:
f[k][j]=min{f[k-1][j]+cost(k,j,i)};
cost发现不能快速的算出。于是不能用类似单调队列+二分的方法来做了。
考虑分治,solve(Head,Tail,L,R,w)当分治区间为Head,Tail,L,R为转移的区间,那么可以直接扫一遍找到转移的最优位置k,然后分治下去。分治的过程中,维护每个数出现了几次(cnt数组),在进入下一层的时候,更新了下层用到的区间的cnt。
代码:
/*
* @Author: mjt
* @Date: 2018-10-15 11:28:17
* @Last Modified by: mjt
* @Last Modified time: 2018-10-15 14:40:30
*/
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#include<iostream>
#include<cctype>
#include<set>
#include<vector>
#include<queue>
#include<map>
#define fi(s) freopen(s,"r",stdin);
#define fo(s) freopen(s,"w",stdout);
using namespace std;
typedef long long LL; inline int read() {
int x=,f=;char ch=getchar();for(;!isdigit(ch);ch=getchar())if(ch=='-')f=-;
for(;isdigit(ch);ch=getchar())x=x*+ch-'';return x*f;
} const int N = ; int a[N], cnt[N];
LL f[N], g[N]; #define add(x) w += cnt[x], cnt[x] ++
#define del(x) cnt[x] --, w-= cnt[x] void solve(int Head,int Tail,int L,int R,LL w) { // w保存(L~R)中,非(Head~Tail),区间的值,即L~min(R,Head)。
if (Head > Tail) return ;
int mid = (Head + Tail) >> , p = min(R, mid), k = ;
for (int i=Head; i<=mid; ++i) add(a[i]);
for (int i=L; i<=p; ++i) {
del(a[i]); // 从i转移,所以i左边的数,不应该被算入贡献,所以要减去。
if (f[mid] > g[i] + w) f[mid] = g[i] + w, k = i;
} for (int i=Head; i<=mid; ++i) del(a[i]);
for (int i=L; i<=p; ++i) add(a[i]);
solve(Head, mid - , L, k, w); for (int i=L; i<k; ++i) del(a[i]);
for (int i=Head; i<=mid; ++i) add(a[i]);
solve(mid + , Tail, k, R, w); for (int i=Head; i<=mid; ++i) del(a[i]); // 初始为递归进来时候的cnt数组。
for (int i=L; i<k; ++i) add(a[i]);
}
int main() {
int n = read(), k = read();
for (int i=; i<=n; ++i) {
a[i] = read();
f[i] = f[i - ] + cnt[a[i]];
cnt[a[i]] ++;
}
memset(cnt, , sizeof(cnt));
while (-- k) {
swap(f, g);
memset(f, 0x3f, sizeof(f));
solve(, n, , n, );
}
cout << f[n];
return ;
}
CF 868 F. Yet Another Minimization Problem的更多相关文章
- CF868 F. Yet Another Minimization Problem 决策单调优化 分治
目录 题目链接 题解 代码 题目链接 CF868F. Yet Another Minimization Problem 题解 \(f_{i,j}=\min\limits_{k=1}^{i}\{f_{k ...
- Codeforces 868F Yet Another Minimization Problem 决策单调性 (看题解)
Yet Another Minimization Problem dp方程我们很容易能得出, f[ i ] = min(g[ j ] + w( j + 1, i )). 然后感觉就根本不能优化. 然后 ...
- Codeforces 868F Yet Another Minimization Problem(分治+莫队优化DP)
题目链接 Yet Another Minimization Problem 题意 给定一个序列,现在要把这个序列分成k个连续的连续子序列.求每个连续子序列价值和的最小值. 设$f[i][j]$为前 ...
- Yet Another Minimization Problem
Yet Another Minimization Problem 一个很显然的决策单调性. 方程是很显然的 $ f_i = \min{f_{j-1} + w(j,i)} $ . 它具有决策单调性,可以 ...
- CF 633 F. The Chocolate Spree 树形dp
题目链接 CF 633 F. The Chocolate Spree 题解 维护子数答案 子数直径 子数最远点 单子数最长直径 (最长的 最远点+一条链) 讨论转移 代码 #include<ve ...
- CF #271 F Ant colony 树
题目链接:http://codeforces.com/contest/474/problem/F 一个数组,每一次询问一个区间中有多少个数字可以整除其他所有区间内的数字. 能够整除其他所有数字的数一定 ...
- 几何入门合集 gym101968 problem F. Mirror + gym102082 Problem F Fair Chocolate-Cutting + gym101915 problem B. Ali and Wi-Fi
abstract: V const & a 加速 F. Mirror 题意 链接 问题: 有n个人在y=0的平面上(及xoz平面).z=0平面上有一面镜子(边平行于坐标轴).z=a平面上有q个 ...
- CF 494 F. Abbreviation(动态规划)
题目链接:[http://codeforces.com/contest/1003/problem/F] 题意:给出一个n字符串,这些字符串按顺序组成一个文本,字符串之间用空格隔开,文本的大小是字母+空 ...
- CF 1051 F. The Shortest Statement
F. The Shortest Statement http://codeforces.com/contest/1051/problem/F 题意: n个点,m条边的无向图,每次询问两点之间的最短路. ...
随机推荐
- Odoo中的模型在哪里
Odoo 模型存在 Python 的模块之外, 在中间注册表那里. 对于这个注册表,可以通过self.env[<model name>]进入,例如, 通过res.partner 模型获取对 ...
- C/C++——指针,引用做函数形参
函数中的形参是普通形参的时,函数只是操纵的实参的副本,而无法去修改实参. 引用形参是对实参的直接操纵,指针形参是对 它所指向的值(*p) 的直接操纵,但是对于这个指针变量(p)来说,依然只是副本. 指 ...
- 【webpack】理解配置文件
学习链接: http://blog.csdn.net/hongchh/article/details/55113751 https://segmentfault.com/a/1190000009356 ...
- virtualbox+vagrant学习-4-Vagrantfile-7-WinRM Settings
WinRM Settings 配置命名空间config.winrm config.winrm配置与如何通过winrm配置vagrant访问你的Windows客户相关.与大多数vagrant设置一样,默 ...
- vector详讲(二)迭代器
先看一下代码: #include <iostream> #include <vector> int main() { std::vector<double> dou ...
- Java中如何判断一个字符串是否为数字
方法一:异常处理 public static boolean isInteger(String str){ try { Integer i = Integer.parseInt(str); retur ...
- mysql将日期字符串转换
举个例子: 给定字符串为07/31/2018,想要把格式转换成20180731 需要用到以下两个函数: date_format(date,’%Y-%m-%d’) ————–>oracle中的to ...
- CSS网页布局:盒子模型
一.盒子模型 标准盒子模型(W3C盒子) 不论是标准盒模型还是IE盒子模型,都有content.padding.border.margin四个部分组成,但从上图也可以看出W3C盒子和IE盒子主要区别在 ...
- from表单提交之前数据判空
在input标签中写onclick事件,不管返回是真是假都会继续提交表单. 使用onsubmit事件 <form action="login.html" method='po ...
- 从对集合数据去重到Distinct源码分析
今天在写代码的时候要对数据进行去重,正打算使用Distinct方法的时候,发现这个用了这么久的东西,竟然不知道它是怎么实现的,于是就有了这篇文章. 使用的.net core2.0 1.需求 假如我们有 ...