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 ;
}

最新文章

  1. 关于flume配置加载(二)
  2. PostgreSQL 在centos 7下的安装配置
  3. TCP发消息续传文件
  4. 连接QuickBooks Online实现于IOS App数据同步功能的个人记录
  5. http://www.myexception.cn/program/767123.html
  6. js基础第二天
  7. 常用mysql笔记
  8. iOS开发之Xcode8推出的WKWebView与UIWebView的使用
  9. Java线程小刀牛试
  10. 第一部分牛刀小试:启动GDB开始调试
  11. WDA-2-事件执行先后
  12. 搭建Fabric网络(一)安装开发工具
  13. 跟我学算法-图像识别之图像分类(下)(GoogleNet网络, ResNet残差网络, ResNext网络, CNN设计准则)
  14. linux - 【LAMP环境配置安装注意安装步骤】 9
  15. Windows MongoDB安装配置
  16. Android AOSP 单独编译某一模块
  17. jenkins 离线安装插件 ,插件的下载地址
  18. 斯坦福CS229机器学习课程笔记 part2:分类和逻辑回归 Classificatiion and logistic regression
  19. layout焊盘过孔大小的设计标准
  20. python 高阶函数和匿名函数

热门文章

  1. BZOJ 1562 变换序列 二分图匹配+字典序
  2. POJ 1050 To the Max 最大子矩阵和(二维的最大字段和)
  3. Reading HPSRouter A High Performance Software Router
  4. 【Step By Step】将Dotnet Core部署到Docker(中)
  5. 每天to do list
  6. SQL引用DAL
  7. sqlplus连接半天才连上
  8. css一边固定,另一边自适应的方法
  9. git 设置只输入一次用户名和密码
  10. thinkphp5.1 学习笔记 【多态关联】