[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件工作分 ...
随机推荐
- cmd下载慢
是网络的原因,加一个镜像服务器 pip install *** -i https://pypi.tuna.tsinghua.edu.cn/simple
- 浅谈一手MYSQL设计规范
前言: 最近牵头搞一个机场管理集团的项目,发现团队中的成员对于库表设计,有非常多的盲区.所以决定写一篇文章,总结一下最近工作的几年中,常用的一些数据库设计规范和思路. 目的 MySQL数据库与 Ora ...
- Java:Object对象小记
Java:Object对象小记 对 Java 中的 Object 对象,做一个微不足道的小小小小记 Object 的常用方法有哪些 clone() 方法:用于创建并返回当前对象的一份拷贝: 在Java ...
- UltraSoft - Alpha - Scrum Meeting 3
Date: Apr 15th, 2020. 会议内容为 贡献分确定与进度汇报. Scrum 情况汇报 进度情况 组员 负责 昨日进度 后两日任务 CookieLau PM.后端 学习前后端分离技术的项 ...
- [软软软]技术博客-Commitizen优化git commit
工具介绍 commitizen/cz-cli是一个规范git commit的工具,使用它代替git commit能够方便有效地写好提交的log,使得团队项目的版本信息更清晰. 安装 (全局安装) np ...
- oo第一单元学习总结
写在开头: 第一次接触面向对象思想和java语言,在学习以及完成作业的过程经历了一个比较痛苦的过程, 虽然在每次写作业时总是会有一些小小的抱怨,虽然写出的代码还是很差, 但是看到自己有所进步,还是感觉 ...
- NKOJ-2936 城市建设
问题描述: PS国是一个拥有诸多城市的大国,国王Louis为城市的交通建设可谓绞尽脑汁.Louis可以在某些城市之间修建道路,在不同的城市之间修建道路需要不同的花费.Louis希望建造最少的道路使得国 ...
- VS2019、Qt5.12及QGis3.16开发常见问题汇总
在C++.Qt软件开发过程中,常常遇到一些编译错误或警告:本文将VS2019.Qt5.12.10和QGis3.16.10的二次开发过程常见的问题做了整理,供大家参考,也便于日后查阅.该内容分为四部分: ...
- Linux入门所必备的Linux命令和C语言基础
文件和目录(底部有视频资料) cd /home 进入 '/ home' 目录' cd - 返回上一级目录 cd -/- 返回上两级目录 cd 进入个人的主目录 cd ~user1 进入个人的主目录 c ...
- Java之父 James Gosling 发表博文 《Too Soon》纪念乔布斯。
几个礼拜前,我们还在讨论乔布斯的辞职.虽然我们都知道这意味着什么,但是我没有想到一切来的如此之快.已经有很多关于这件事情的文章了,特别是"经济学人"的这篇文章. 乔布斯是一个很独特 ...