https://vjudge.net/problem/HDU-4261


对于一个长2000的数列划分最多25个块,每块代价为块内每个数与块内中位数差的绝对值之和,求最小总代价。


套路化地,设$f[i][j]$表示第$i$位,划了$j$块最小代价。然后dp。$O(n^3k)$不必说。($logn$和$k$看成同数量级,其实是$O(n^3(k+logn))$)

然后重点在于找中位数。上述暴力浪费在于每段区间中位数都要寻找一遍。可以用对顶堆(其实是不想写平衡树,或者不会更优秀,码量更小的玩意儿了),动态维护中位数,不多说了。求代价就是对两个堆总和记$s1,s2$,配合中位数即可算出,每算出一段的代价就顺便转移。

然后就$O(n^2k)$了。

不知道为什么跑那么快,直接在hdu屠榜rk1了。。qwq

Upd:被2人超过了。。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<queue>
#define dbg(x) cerr<<#x<<" = "<<x<<endl
#define _dbg(x,y) cerr<<#x<<" = "<<x<<" "<<#y<<" = "<<y<<endl
using namespace std;
typedef long long ll;
template<typename T>inline char MIN(T&A,T B){return A>B?A=B,:;}
template<typename T>inline char MAX(T&A,T B){return A<B?A=B,:;}
template<typename T>inline T _min(T A,T B){return A<B?A:B;}
template<typename T>inline T _max(T A,T B){return A>B?A:B;}
template<typename T>inline T read(T&x){
x=;int f=;char c;while(!isdigit(c=getchar()))if(c=='-')f=;
while(isdigit(c))x=x*+(c&),c=getchar();return f?x=-x:x;
}
const int N=+;
ll f[N][],s1,s2,res;
int a[N];
int n,m; int main(){//freopen("test.in","r",stdin);//freopen("test.out","w",stdout);
while(read(n),read(m),n||m){
for(register int i=;i<=n;++i)read(a[i]);
memset(f,0x01,sizeof f);f[][]=;
for(register int i=;i<n;++i){
priority_queue<int> q1;
priority_queue<int,vector<int>,greater<int> > q2;
s1=s2=res=;
for(register int j=i+;j<=n;++j){
if(q1.empty()||a[j]<=q1.top())q1.push(a[j]),s1+=a[j];else q2.push(a[j]),s2+=a[j];
while(q1.size()>q2.size()+)s1-=q1.top(),s2+=q1.top(),q2.push(q1.top()),q1.pop();
while(q2.size()>q1.size())s2-=q2.top(),s1+=q2.top(),q1.push(q2.top()),q2.pop();
res=(q1.size()-q2.size())*1ll*q1.top()-s1+s2;
for(register int k=;k<m;++k)MIN(f[j][k+],f[i][k]+res);
}
}
printf("%lld\n",f[n][m]);
}
return ;
}

hdu4261 Estimation[暴力dp+对顶堆]的更多相关文章

  1. HDU4261 Estimation

    题意 Estimation Time Limit: 40000/15000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others ...

  2. hdu3282 链表或者对顶堆

    维护序列的动态中位数 第一次用链表做题..感觉指针指来指去也挺麻烦的.. 本题链表解法就是用数组模拟出一个链表,然后离线输入所有数,排序,按照输入顺序在链表里删除元素,一次性删掉两个,然后中位数指针对 ...

  3. 【uoj#280】[UTR #2]题目难度提升 对顶堆+STL-set

    题目描述 给出 $n$ 个数 $a_1,a_2,...,a_n$ ,将其排为序列 $\{p_i\}$ ,满足 $\{前\ i\ 个数的中位数\}$ 单调不降.求字典序最大的 $\{p_i\}$ . 其 ...

  4. 【POJ 3784】 Running Median (对顶堆)

    Running Median Description For this problem, you will write a program that reads in a sequence of 32 ...

  5. Luogu P1436 棋盘分割 暴力DP

    我的天,,,,,n=8,k<=15,,,这怕不是暴力DP+高维数组.... 开一个五维数组f[k][i][j][p][q]表示从(i,j)到(p,q)中分成k个矩形最小的平方和. 然后初始化时用 ...

  6. P1168 中位数(对顶堆)

    题意:维护一个序列,两种操作 1.插入一个数 2.输出中位数(若长度为偶数,输出中间两个较小的那个) 对顶堆 维护一个小根堆,一个大根堆,大根堆存1--mid,小根堆存mid+1---n 这样堆顶必有 ...

  7. poj3784 Running Median[对顶堆]

    由于我不会讲对顶堆,所以这里直接传上一个巨佬的学习笔记. 对顶堆其实还是很容易理解的,想这题的时候自己猜做法也能把没学过的对顶堆给想出来.后来了解,对顶堆主要还是动态的在线维护集合$K$大值.当然也可 ...

  8. 洛谷 - P1801 - 黑匣子 - 对顶堆

    这道题是提高+省选-的难度,做出来的话对数据结构题目的理解会增加很多. 可以使用一种叫做对顶堆的东西,对顶堆是在线维护第n小的logn的算法.大概的思路是,假如我们要找的是第n小,我们就维护一个大小为 ...

  9. bzoj 1112: [POI2008]砖块Klo【对顶堆】

    priority_queue实现的对顶堆,细节超级多WA了十几次--但是理论上是最简便的orz其实是我已经不会写平衡树了 枚举左端点,显然要把这一段的高度搞成(l,l+k-1)的高度中位数,所以需要一 ...

随机推荐

  1. 使用 Vs 2015 快速上手 Angular2

    Visual Studio 2015 快速上手(使用Angular2)https://angular.cn/guide/visual-studio-2015 使用 Vs 2015 快速上手 Angul ...

  2. 解决无法启动mysql服务错误1069

    之前在服务器上修改了my.ini文件 mysql就一直无法启动 后来把my.ini改回原来的,还是无法启动并报1069错误 在网上查了一下,基本上都是说修改mysql密码,再重新启动,试了一下没作用, ...

  3. SpringMVC - 多个同名name提交与后台参数解析

    简洁来说,就是form表单有多个input(checkbox,hidden),name同名,后台是如何接收的. [1]多个inpu 同名name form表单如下: <form action=& ...

  4. HDU-4679-树的直径(树形dp)

    Terrorist’s destroy Time Limit: 6000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  5. 利用ftrace跟踪内核static tracepoint

    摘要:和很多linux内核子系统一样,static tracepoint有很多层次,其中某个层次都展示给不同层次的开发者来满足他们的不同需求.关于linux tracepoint的详细信息,我们可以在 ...

  6. ElementUI组件Cascader级联选择器数据后台处理

    Cascader级联选择器数据数据格式不知道的可以去官网看下:这里我就不表示什么了. 部门实体类: import lombok.Data; @Data public class Department ...

  7. 【后台测试】postman简介

    ◆版权声明:本文出自胖喵~的博客,转载必须注明出处. 转载请注明出处:http://www.cnblogs.com/by-dream/p/6266047.html 在接口测试的过程中,经常拿到一个接口 ...

  8. Python的介绍及Pycharm软件的安装

    一.Python介绍 1.  Python是一种解释性.面向对象.动态数据类型的高级程序设计语言. Python语言创始人是吉多.范罗苏姆:起源与1989年 2.  缺点:运行速度慢(由于是解释性语言 ...

  9. Java并发编程之读写锁

    读写锁维护了一对相关的锁,一个用于只读操作,一个用于写入操作.只要没有writer,读取锁可以由多个reader线程同时保持.写入锁是独占的. 可重入读写锁 ReentrantReadWriteLoc ...

  10. MPAndroidChart Wiki(译文)~Part 4

    16. 动画 注意:本章的动画效果只会在API 11(Android3.0.x)及以上的Android版本上生效 在低于上述的Android版本中,动画将不会被执行,并不会导致程序崩溃. 所有类型的图 ...