首先暴力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]任务分配问题的更多相关文章

  1. 分配问题与Hungarian算法

    分配问题与Hungarian算法 分配问题 指派问题 匈牙利算法 匈牙利方法是一种能够在多项式时间内解决分配问题(assignment problem)的组合优化算法.它由Harold Kuhn 与1 ...

  2. 关于const和define的内存分配问题的总结

    关于const和define的内存分配问题 const与#define宏定义的区别----C语言深度剖析 1,  const定义的只读变量在程序运行过程中只有一份拷贝(因为它是全局的只读变量,存放在静 ...

  3. 【Uvalive 2531】 The K-League (最大流-类似公平分配问题)

    [题意] 有n个队伍进行比赛,每场比赛,恰好有一支队伍取胜.一支队伍败.每个队伍需要打的比赛场数相同,给你每个队伍目前已经赢得场数和输得场数,再给你一个矩阵,第 i 行第 j 列 表示队伍 i 和队伍 ...

  4. mmc生产任务分配问题

    mmc生产任务分配问题,本题目简单.

  5. dp资源分配问题

    noip考试中dp中的资源分配问题是一大重点(不定时更新) 以下是一些例题 1.乘积最大 //Gang #include<iostream> #include<cstring> ...

  6. 洛谷P4014 分配问题【最小/大费用流】题解+AC代码

    洛谷P4014 分配问题[最小/大费用流]题解+AC代码 题目描述 有 n 件工作要分配给 n 个人做.第 i 个人做第 j 件工作产生的效益为c ij. 试设计一个将 n 件工作分配给 n 个人做的 ...

  7. [20181229]关于字符串的分配问题.txt

    [20181229]关于字符串的分配问题.txt --//链接:http://www.itpub.net/thread-2107534-1-1.html提到的问题,里面一段英文读起来很绕口:--//百 ...

  8. 记一次ElasticSearch重启之后shard未分配问题的解决

    记一次ElasticSearch重启之后shard未分配问题的解决 环境 ElasticSearch6.3.2,三节点集群 Ubuntu16.04 一个名为user的索引,索引配置为:3 primar ...

  9. Libre 6012 「网络流 24 题」分配问题 (网络流,费用流)

    Libre 6012 「网络流 24 题」分配问题 (网络流,费用流) Description 有n件工作要分配给n个人做.第i个人做第j件工作产生的效益为\(c_{ij}\).试设计一个将n件工作分 ...

随机推荐

  1. 微信公众号开发之H5页面跳转到指定的小程序

    前言: 最近公司有一个这样的需要,需要从我们在现有的公众号H5页面中加一个跳转到第三方小程序的按钮.之前只知道小程序之间是可以相互跳转的,今天查阅了下微信开发文档原来现在H5网页也支持小程序之间的跳转 ...

  2. 题解 Children Trips

    题目传送门 Description 给出一个大小为 \(n\) 的边权全为 \(1,2\) 的带权树,有 \(q\) 此查询,每次给出 \(u,v,p\) ,问 \(u\to v\) 每次可以最多走边 ...

  3. FastAPI 学习之路(十一)请求体 - 嵌套模型

    系列文章: FastAPI 学习之路(一)fastapi--高性能web开发框架 FastAPI 学习之路(二) FastAPI 学习之路(三) FastAPI 学习之路(四) FastAPI 学习之 ...

  4. nexus设置npm下载管理

    nexus设置npm下载管理 第一步 登录私服网页 第二步 创建存储空间(如果使用默认的存储空间,此步骤可省略) 第三步 输入空间的名称,点击create创建 第四步 创建仓库 npm的仓库有三种: ...

  5. 【UE4 C++ 基础知识】<9> Interface 接口

    概述 简单的说,接口提供一组公共的方法,不同的对象中继承这些方法后可以有不同的具体实现. 任何使用接口的类都必须实现这些接口. 实现解耦 解决多继承的问题 蓝图使用 使用方法 三种调用方法的区别 调用 ...

  6. 全连接层dense作用

    参考来源

  7. 架构师之路-https底层原理

    引子 先说说我对架构师的理解.从业务能力上,需要的是发现问题和解决问题的能力:从团队建设上,需要的是能培养团队的业务能力:从项目管理上,把控好整个项目和软件产品的全生命周期. 我搜索了一下架构师的培训 ...

  8. NOIP模拟22

    T1d 一道垃圾贪心,写个堆优化或者桶就行 1 #include<bits/stdc++.h> 2 #define int long long 3 using namespace std; ...

  9. 跳台阶 牛客网 剑指Offer

    跳台阶 牛客网 剑指Offer 题目描述 一只青蛙一次可以跳上1级台阶,也可以跳上2级.求该青蛙跳上一个n级的台阶总共有多少种跳法(先后次序不同算不同的结果). class Solution: #ru ...

  10. (三)lamp环境搭建之编译安装php

    1,PRC (People's republic of China) timezone中设置的时间为中国时间. 2,php的官方镜像源,使用linux时可以直接下载的 http://cn2.php.n ...