博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Estimation
阅读量:7094 次
发布时间:2019-06-28

本文共 2133 字,大约阅读时间需要 7 分钟。

给出一个长度为n序列\(\{a_i\}\),将其划分成连续的K段,对于其中一段\([l,r]\),设其中位数为m,定义其权值为\(\sum_{i=l}^r|m-a_i|\),求最小的权值之和,\(n\leq 2000,K\leq 25\)

显然设\(f[i][j]\)表示前i个数划分成j段的的最小权值和,设\(m(i,j)\)\(i\sim j\)的作为一段的权值,所以有

\[f[i][j]=\min_{0\leq k<i}\{f[k][j-1]+m(k+1,i)\}\]

边界:\(f[0][0]=0\),其余无限大

答案:\(f[n][K]\)

注意到时间复杂度\(2000^2\times 25=10^8\),为一亿,可以险过,关键在于快速求二元函数m,而求m需要解决的是动态维护一段序列中中间大的数,显然中位数的位置是递增的,可以考虑双堆堆顶优化,不难得知对于序列\(b_1,b_2,...,b_p\)而言设其中位数为\(b_q\),于是有权值为

\[\sum_{i=1}^p|b_i-b_q|=|b_p-b_q|+...+|b_q-b_q|+...+|b_q-b_1|=\]

\[=b_p-b_q+..+b_q-b_q+...+b_q-b_1=(b_p+...+b_{q+1})-(b_q+...+b_1)+qb_q-(p-q)b_q=\]

\[\sum_{i=q+1}^pb_i-\sum_{i=1}^qb_i+(2q-p)b_q\]

于是对于权值,我们只要维护这样一个式子即可,步骤如下

  1. 枚举左端点i,设大根堆为H,小根堆为E
  2. 初始化\(m(i,i)=0,k=-a_i\),H加入\(a_i\)
  3. 枚举右端点j
  4. 如果\(a_j\leq H.top()\),那么\(E.push(H.top()),H.pop(),k+=E.top()\times 2,H.push(a_j),k-=a_j\)
  5. 否则\(E.push(a_j),k+=a_j\)
  6. 如果\(i-j+1\)为偶数的话,那么\(H.push(E.top()),E.pop(),k-=H.top()\times 2\)
  7. 计入答案\(m(i,j)=k+(2q-p)\times H.top()\)

参考代码:

#include 
#include
#include
#include
#include
#define il inline#define ri register#define intmax 0x7fffffffusing namespace std;int a[2001],m[2001][2001],dp[2001][26];priority_queue
,less
>H;priority_queue
,greater
>E;il void read(int&);int main(){ int n,K; while(read(n),read(K),n&&K){ for(int i(1);i<=n;++i)read(a[i]); for(int i(1),j,k;i<=n;++i){ while(H.size())H.pop(); while(E.size())E.pop(); H.push(a[i]),k=-a[i]; for(j=i+1;j<=n;++j){ if(a[j]<=H.top()) E.push(H.top()),H.pop(),H.push(a[j]), k-=a[j],k+=E.top()<<1; else E.push(a[j]),k+=a[j]; if((j-i+1)&1)k-=E.top()<<1,H.push(E.top()),E.pop(); m[i][j]=k+H.top()*((H.size()<<1)-(j-i+1)); } }memset(dp,2,sizeof(dp)),dp[0][0]=0; for(int i,j(1),k;j<=K;++j) for(i=j;i<=n;++i) for(k=0;k
dp[k][j-1]+m[k+1][i]) dp[i][j]=dp[k][j-1]+m[k+1][i]; printf("%d\n",dp[n][K]); } return 0;}il void read(int &x){ x&=0;ri char c;while(c=getchar(),c==' '||c=='\n'||c=='\r'); ri bool check(false);if(c=='-')check|=true,c=getchar(); while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+(c^48),c=getchar(); if(check)x=-x;}

转载于:https://www.cnblogs.com/a1b3c7d9/p/11031255.html

你可能感兴趣的文章
IBM马修:利用数据分析实现企业创新
查看>>
卡巴斯基:高达98%的WannaCry 受害者运行的是 Windows 7系统
查看>>
PMC 赢得客户认可,获富士通颁发2015年度技术大奖
查看>>
BigBench on MaxCompute 基准测试套件简明安装与运行指南
查看>>
ABB机器人事业部产品架构总监Daniel ppling:面对机器人技术,我们应该关注什么?...
查看>>
《中国人工智能学会通讯》——1.3 若干研究结果
查看>>
IDC指出,NetApp在全闪存市场上位列第二
查看>>
ASLR保护机制被突破的攻击技术分析
查看>>
如何保证CAN网络中通讯的可靠性和节点数
查看>>
衡量云性能:我们需要一把不同于以往的标尺
查看>>
干货|大数据应用:前端模块化开发的价值
查看>>
美国互联网瘫痪谁背锅?安全机构曝光部分厂商名单
查看>>
开发者论坛一周精粹(第十八期) :第一期阿里云高校工作坊申办启动
查看>>
人工智能、机器学习、深度学习的区别在哪?
查看>>
基于Java Socket的自定义协议,实现Android与服务器的长连接(一)
查看>>
中了敲诈者病毒,文件恢复有可能吗?你长着一张被勒索木马敲诈的脸?| 硬创公开课...
查看>>
能否预测下一个安全漏洞?
查看>>
第三季度服务器DRAM合约价续扬,预估季增3%~8%
查看>>
流处理技术谬见大消除
查看>>
是什么让5G的峰值速度高达20Gb/s?一文看懂毫米波技术
查看>>