[题目链接]

http://acm.hdu.edu.cn/showproblem.php?pid=4261

[算法]

首先,有一个结论 :

| a[1] - k | + | a[2] - k | + ... + | a[n] - k | 当k取(a[1],a[2], ... , a[n])的中位数时,式子的值最小

考虑动态维护中位数

我们用一个大根堆和一个小根堆,大根堆中存放前[1..N/2](向上取整)小的数,小根堆中存放[N/2 + 1,N]小的数,还需维护两个变量s1和s2,分别为小根堆中所有数的和和大根堆中所有数的和

这样,我们就可以预处理出每一段的最小值

然后,我们用f[i][j]表示前i个数分成j段取得的最小值,有状态转移方程 :

f[i][j]  = min{ f[k][j - 1] + middle( k + 1,i) ) (其中,middle(k + 1,i)表示[k + 1,i]中每个数与中位数的差值和)

答案即为f[n][k]

[代码]

#include<bits/stdc++.h>
using namespace std;
#define MAXN 2010
#define MAXK 30
const int INF = 2e9; int i,j,k,s1,s2,x,y,n,m,middle;
int a[MAXN],sum[MAXN][MAXN];
int f[MAXN][MAXK]; struct Sheap
{
int tot;
int a[MAXN];
inline void clear()
{
tot = ;
}
inline void up(int now)
{
if (now == ) return;
int fa = now >> ;
if (a[now] < a[fa])
{
swap(a[now],a[fa]);
up(fa);
}
}
inline void down(int now)
{
int son = now << ;
if (son > tot) return;
if (son + <= tot && a[son + ] < a[son]) son++;
if (a[son] < a[now])
{
swap(a[son],a[now]);
down(son);
}
}
inline void insert(int x)
{
a[++tot] = x;
up(tot);
}
inline void del()
{
swap(a[],a[tot]);
tot--;
down();
}
inline int getroot()
{
return a[];
}
} S;
struct Bheap
{
int tot;
int a[MAXN];
inline void clear()
{
tot = ;
}
inline void up(int now)
{
if (now == ) return;
int fa = now >> ;
if (a[now] > a[fa])
{
swap(a[now],a[fa]);
up(fa);
}
}
inline void down(int now)
{
int son = now << ;
if (son > tot) return;
if (son + <= tot && a[son + ] > a[son]) son++;
if (a[son] > a[now])
{
swap(a[now],a[son]);
down(son);
}
}
inline void insert(int x)
{
a[++tot] = x;
up(tot);
}
inline void del()
{
swap(a[],a[tot]);
tot--;
down();
}
inline int getroot()
{
return a[];
}
} B; int main()
{ while (scanf("%d%d",&n,&m) && (n || m))
{
for (i = ; i <= n; i++) scanf("%d",&a[i]);
for (i = ; i <= n; i++)
{
B.clear();
S.clear();
sum[i][i] = ;
B.insert(a[i]);
s1 = a[i];
s2 = ;
for (j = i + ; j <= n; j++)
{
if (B.tot <= (j - i) / )
{
B.insert(a[j]);
s1 += a[j];
} else
{
S.insert(a[j]);
s2 += a[j];
}
x = B.getroot();
y = S.getroot();
if (x > y)
{
B.del();
s1 -= x;
S.del();
s2 -= y;
S.insert(x);
s2 += x;
B.insert(y);
s1 += y;
}
middle = B.getroot();
sum[i][j] = middle * B.tot - s1 + s2 - middle * S.tot;
}
}
for (i = ; i <= n; i++)
{
for (j = ; j <= m; j++)
{
f[i][j] = INF;
}
}
for (i = ; i <= n; i++) f[i][] = sum[][i];
for (i = ; i <= n; i++)
{
for (j = ; j <= m; j++)
{
for (k = i - ; k >= ; k--)
{
f[i][j] = min(f[i][j],f[k][j - ] + sum[k + ][i]);
}
}
}
printf("%d\n",f[n][m]);
} return ; }

[HDU 4261] Estimation的更多相关文章

  1. 【HDOJ】4261 Estimation

    挺不错的一道题,基本思路是dp.关键点是如何求区间内的Sigma|A_i-B_i|.线段树做TLE了,优先队列可以过. /* 4261 */ #include <iostream> #in ...

  2. $2019$ 暑期刷题记录1:(算法竞赛DP练习)

    $ 2019 $ 暑期刷题记录: $ POJ~1952~~BUY~LOW, BUY~LOWER: $ (复杂度优化) 题目大意:统计可重序列中最长上升子序列的方案数. 题目很直接的说明了所求为 $ L ...

  3. hdu 4882 ZCC Loves Codefires(数学题+贪心)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4882 ------------------------------------------------ ...

  4. HDU 5130 Signal Interference(计算几何 + 模板)

    HDU 5130 Signal Interference(计算几何 + 模板) 题目链接http://acm.hdu.edu.cn/showproblem.php?pid=5130 Descripti ...

  5. D - 淡黄的长裙 HDU - 4221(贪心)

    D - 淡黄的长裙 HDU - 4221(贪心) James is almost mad! Currently, he was assigned a lot of works to do, so ma ...

  6. 萌新笔记——Cardinality Estimation算法学习(一)(了解基数计算的基本概念及回顾求字符串中不重复元素的个数的问题)

    最近在菜鸟教程上自学redis.看到Redis HyperLogLog的时候,对"基数"以及其它一些没接触过(或者是忘了)的东西产生了好奇. 于是就去搜了"HyperLo ...

  7. HDOJ 2111. Saving HDU 贪心 结构体排序

    Saving HDU Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  8. 【HDU 3037】Saving Beans Lucas定理模板

    http://acm.hdu.edu.cn/showproblem.php?pid=3037 Lucas定理模板. 现在才写,noip滚粗前兆QAQ #include<cstdio> #i ...

  9. hdu 4859 海岸线 Bestcoder Round 1

    http://acm.hdu.edu.cn/showproblem.php?pid=4859 题目大意: 在一个矩形周围都是海,这个矩形中有陆地,深海和浅海.浅海是可以填成陆地的. 求最多有多少条方格 ...

随机推荐

  1. 【HTTP】如何正常关闭连接

    参考:<HTTP权威指南> 所有HTTP客户端.服务器或者代理都可以任意时刻关闭一条TCP传输连接.但是服务器永远无法确定它关闭“空闲”连接的那一刻,在线路那一头的客户端有没有数据要发送. ...

  2. Multipart/form-data POST文件上传

    简单的HTTP POST 大家通过HTTP向服务器发送POST请求提交数据,都是通过form表单提交的,代码如下: <form method="post"action=&qu ...

  3. GO 协程 通道实例以及验证SnowFlake算法

    最近项目中使用了SnowFlake算法产生ID,并在实际运行环境下会产生重复ID,所以写了一个Go的程序进行验证,顺便也练习一下Go的协程与通道. 至于GO的协程和通道的基础知识请自行百度. 代码如下 ...

  4. windows和linux无法访问VMware中linux的tomcat主页问题

    1.一定确定自己的tomcat服务器是启动的.(为了确保保险可以在测试前重新shutdown,startup一次) 2.确定自己访问的ip地址和端口号是正确的 如果是VMware外部windows的话 ...

  5. C# Datetime 使用详解

    获得当前系统时间: DateTime dt = DateTime.Now; Environment.TickCount可以得到“系统启动到现在”的毫秒值 DateTime now = DateTime ...

  6. XML、集合、JSP综合练习

    一.利用DOM解析XML文件得到信息:存入泛型集合中在JSP页面循环打印读取的信息 a)         编写XML文件:添加测试节点数据 b)         建立web项目:在JSP页面中使用DO ...

  7. java输入输入流图解

  8. 不能访问windows installer 服务,可能你在安全模式下运行 windows ,或者windows installer

    windows installer服务解决方案 很多朋友在安装MSI格式的文件包时,经常会遇到windows installer出错的情况,有如下几种现象: 1.所有使用windows install ...

  9. boost asio异步读写网络聊天程序客户端 实例详解

    boost官方文档中聊天程序实例讲解 数据包格式chat_message.hpp <pre name="code" class="cpp">< ...

  10. List分组的两种方式

    java8之前List分组 假设有个student类,有id.name.score属性,list集合中存放所有学生信息,现在要根据学生姓名进行分组. public Map<String, Lis ...