[luogu5574]任务分配问题
首先暴力dp,令$f_{i,j}$表示前$i$个点划分为$j$段,即有转移$f_{i,j}=\min f_{k-1,j-1}+calc(k,i)$(其中$calc(i,j)$表示求区间$[i,j]$的顺序对数)
可以先枚举$j$,记$g_{i}=f_{i,j-1}$,则$f_{i}=\min g_{k-1}+calc(k,i)$,先$o(k)$枚举以下层数,快速支持上述转移
令$mn_{i}$为取到最小值的最小的$k$,即有$f_{i}=g_{mn_{i}-1}+calc(mn_{i},i)$,则有$mn_{i}\le mn_{i+1}$(即决策单调性),证明如下:
反证法,若$mn_{i}>mn_{i+1}$(为方便表示,以下记$x=mn_{i}$、$y=mn_{i+1}$),则由于其都是最小的转移,则有:$g_{x-1}+calc(x,i)\le g_{y-1}+calc(y,i)$,$g_{x-1}+calc(x,i+1)\ge g_{y-1}+calc(y,i+1)$
将第二个式子乘上-1后与第一个式子分别相加,可得$calc(x,i)-calc(x,i+1)\le calc(y)-calc(y,i+1)$
考虑顺序对的意义(即代入顺序对的式子),即$-\sum_{j=x}^{i}[a_{j}\le a_{i+1}]\le -\sum_{j=y}^{i}[a_{j}\le a_{i+1}]$
由于$x>y$,将右式加过来,即$\sum_{j=y}^{x-1}[a_{j}\le a_{i+1}]\le 0$,由于左式非负,因此必然取等号
考虑这个式子是由最初两个式子相加,因此也应取到等号,即$g_{x-1}+calc(x,i)=g_{y-1}+calc(y,i)$,这与$mn_{i}$为最小的$k$矛盾
接下来考虑如何来维护这个$mn_{i}$,直接整体二分,即求出$mn_{mid}$,然后划分为两部分即可
但还有一个问题,考虑如何求$mn_{mid}$,假设询问区间为$[l,r]$,答案(即$mn_{i}$)对应区间为$[x,y]$,此时如果暴力求$[y,mid]$内的顺序对数复杂度显然是不对的,因此考虑优化
类似莫队,维护一个区间$[l',r']$以及该区间内的顺序对数,之后通过移动$l'$和$r'$(需要可持久化线段树维护移动)来得到该区间,接下来每次移动次数为$o((y-x)+(r-l))$,由此即可得总复杂度为$o(nk\log^{2}n)$
首先,每一次开始时,$l'\in [x,y]$且$r'\in [l,r]$(可以归纳),此时相当于要将$r'$移动到$mid$,再将$l'$移动到$y$再移动回$x$,这些年都是$o((y-x)+(r-l))$的
之后考虑将$l'$移动回到$mn_{mid}$,进行搜索左区间,再将$r'$移动到$mid+1$来搜索右区间,最后再把$l'$和$r'$移动回最开始的状态,这样就可以保证复杂度
(由于$|a-b|+|b-c|\ge |a-c|$,这个移动并不需要去实现,而只是证明复杂度)

1 #include<bits/stdc++.h>
2 using namespace std;
3 #define N 25005
4 #define mid (l+r>>1)
5 int V,n,k,ll,rr,a[N],rt[N],tr[N*20],ls[N*20],rs[N*20];
6 long long sum,g[N],f[N];
7 int New(int k){
8 tr[++V]=tr[k];
9 ls[V]=ls[k];
10 rs[V]=rs[k];
11 return V;
12 }
13 void update(int &k,int l,int r,int x){
14 k=New(k);
15 tr[k]++;
16 if (l==r)return;
17 if (x<=mid)update(ls[k],l,mid,x);
18 else update(rs[k],mid+1,r,x);
19 }
20 int query(int k,int l,int r,int x,int y){
21 if ((!k)||(l>y)||(x>r))return 0;
22 if ((x<=l)&&(r<=y))return tr[k];
23 return query(ls[k],l,mid,x,y)+query(rs[k],mid+1,r,x,y);
24 }
25 int calcl(int x,int y){
26 return query(rt[y],1,n,a[x]+1,n)-query(rt[x],1,n,a[x]+1,n);
27 }
28 int calcr(int x,int y){
29 return query(rt[y-1],1,n,1,a[y]-1)-query(rt[x-1],1,n,1,a[y]-1);
30 }
31 long long calc(int x,int y){
32 while (rr<y)sum+=calcr(ll,++rr);
33 while (x<ll)sum+=calcl(--ll,rr);
34 while (ll<x)sum-=calcl(ll++,rr);
35 while (y<rr)sum-=calcr(ll,rr--);
36 return sum;
37 }
38 void dfs(int l,int r,int x,int y){
39 if (l>r)return;
40 int s=0,k=0;
41 f[mid]=0x3f3f3f3f;
42 for(int i=x;i<=min(mid,y);i++){
43 int s=g[i-1]+calc(i,mid);
44 if (s<f[mid]){
45 f[mid]=s;
46 k=i;
47 }
48 }
49 dfs(l,mid-1,x,k);
50 dfs(mid+1,r,k,y);
51 }
52 int main(){
53 scanf("%d%d",&n,&k);
54 for(int i=1;i<=n;i++)scanf("%d",&a[i]);
55 for(int i=1;i<=n;i++){
56 rt[i]=rt[i-1];
57 update(rt[i],1,n,a[i]);
58 }
59 ll=1,rr=0;
60 for(int i=1;i<=n;i++)f[i]=calc(1,i);
61 for(int i=1;i<k;i++){
62 memcpy(g,f,sizeof(g));
63 dfs(1,n,1,n);
64 }
65 printf("%d",f[n]);
66 }
[luogu5574]任务分配问题的更多相关文章
- 分配问题与Hungarian算法
分配问题与Hungarian算法 分配问题 指派问题 匈牙利算法 匈牙利方法是一种能够在多项式时间内解决分配问题(assignment problem)的组合优化算法.它由Harold Kuhn 与1 ...
- 关于const和define的内存分配问题的总结
关于const和define的内存分配问题 const与#define宏定义的区别----C语言深度剖析 1, const定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静 ...
- 【Uvalive 2531】 The K-League (最大流-类似公平分配问题)
[题意] 有n个队伍进行比赛,每场比赛,恰好有一支队伍取胜.一支队伍败.每个队伍需要打的比赛场数相同,给你每个队伍目前已经赢得场数和输得场数,再给你一个矩阵,第 i 行第 j 列 表示队伍 i 和队伍 ...
- mmc生产任务分配问题
mmc生产任务分配问题,本题目简单.
- dp资源分配问题
noip考试中dp中的资源分配问题是一大重点(不定时更新) 以下是一些例题 1.乘积最大 //Gang #include<iostream> #include<cstring> ...
- 洛谷P4014 分配问题【最小/大费用流】题解+AC代码
洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...
- [20181229]关于字符串的分配问题.txt
[20181229]关于字符串的分配问题.txt --//链接:http://www.itpub.net/thread-2107534-1-1.html提到的问题,里面一段英文读起来很绕口:--//百 ...
- 记一次ElasticSearch重启之后shard未分配问题的解决
记一次ElasticSearch重启之后shard未分配问题的解决 环境 ElasticSearch6.3.2,三节点集群 Ubuntu16.04 一个名为user的索引,索引配置为:3 primar ...
- Libre 6012 「网络流 24 题」分配问题 (网络流,费用流)
Libre 6012 「网络流 24 题」分配问题 (网络流,费用流) Description 有n件工作要分配给n个人做.第i个人做第j件工作产生的效益为\(c_{ij}\).试设计一个将n件工作分 ...
随机推荐
- caffe转换变量时的gflags问题
先解决错误7,解决方式来自于http://blog.csdn.net/wishchin/article/details/51888566这篇博文,感谢博主 只需要添加上 #pragma comment ...
- 从零入门 Serverless | SAE 的远程调试和云端联调
作者 | 弈川 阿里巴巴云原生团队 导读:本节课程包含三部分内容,前两个部分简单介绍远程调试以及端云联调的原理,最后在 Serverless 应用引擎中进行实际演示. 经过之前课程的学习,相信大家对于 ...
- 学校选址(ArcPy实现)
一.背景 合理的学校空间位置布局,有利于学生的上课与生活.学校的选址问题需要考虑地理位置.学生娱乐场所配套.与现有学校的距离间隔等因素,从总体上把握这些因素能够确定出适宜性比较好的学校选址区. 二.目 ...
- 【集成学习】:Stacking原理以及Python代码实现
Stacking集成学习在各类机器学习竞赛当中得到了广泛的应用,尤其是在结构化的机器学习竞赛当中表现非常好.今天我们就来介绍下stacking这个在机器学习模型融合当中的大杀器的原理.并在博文的后面附 ...
- c++-string类--insert函数
string &insert(int p0, const char *s);--在p0位置插入字符串s string &insert(int p0, const char *s, in ...
- xpath helper插件安装提示程序包无效
参考链接:https://www.jianshu.com/p/b7d782ef81e0 刚学到爬虫,需要在Chrome浏览器安装xpath helper插件结果一直提示"程序包无效" ...
- iOS路由最佳选择是什么
背景 记得四年前iOS路由开始盛行,当时比较有名的是蘑菇街的,后来CTMediator写了几篇文章把蘑菇街批的体无完肤,导致我后来写新项目用了CTMediator,那一堆组件创建的叫一个酸爽啊!再后来 ...
- 240.搜索二维矩阵II
从左下角位置开始搜索 时间复杂度:O(行数+列数). 想法有点像二分法,大了往一个方向找,小了往另一个方向找.由于矩阵横向和纵向都是递增,如果从(0,0)位置开始找,往右和往下都是增大,因此不知道实际 ...
- 新型活跃Mozi样本分析报告
基本信息 对象 值 文件名 Photo.scr 文件类型 PE32 executable for MS Windows (GUI) Intel 80386 32-bit 文件大小 6271259 by ...
- 《手把手教你》系列技巧篇(三十四)-java+ selenium自动化测试-单选和多选按钮操作-中篇(详解教程)
1.简介 今天这一篇宏哥主要是讲解一下,如何使用list容器来遍历单选按钮.大致两部分内容:一部分是宏哥在本地弄的一个小demo,另一部分,宏哥是利用JQueryUI网站里的单选按钮进行实战. 2.d ...