题目大意:给定一个长度为n的序列,至多将序列分成m+1段,每段序列都有权值,权值为序列内两个数两两相乘之和。m<=n<=1000.

分析:令w[i,j]表示区间[i,j]中两两乘积之和,f[i][j]表示前j个数分成i段的最小值。

f[i][j]=f[i-1][k]+w[k+1,j]
w[k+1,j]可以转换为w[1,j]-w[1,k]-sum[k]*(sum[j]-sum[k])
其中sum[j]表示前j个数的前缀和。
f[i][j]=f[i-1][k]+w[j]-w[k]-sum[k]*(sum[j]-sum[k])
令y=f[i-1][k]+w[j]-w[k]+sum[k]^2,x=sum[k],b=sum[j],g=f[i][j],则有:

y-bx=g

此为直线方程,b为定值,要求g最小,即为直线的截距最小。平面上有若干点(x,y),这些点是由各个决策点产生的。而将直线从下往上平移,它接触到的第一个点即为最佳决策点。因为斜率b是上升的,所以,下一阶段的直线方程斜率更高,于是最佳决策点一定形成了下凸包序列。

#include<iostream>
#include<cstdio>
#include<cstring>
#define MAXN 1005
#define LL long long int
LL f[MAXN][MAXN],w[MAXN],sum[MAXN];
#define FZ(i,p) (f[i-1][p]-w[p]+sum[p]*sum[p])
int n,m,num[MAXN];
int que[MAXN],head,tail;
#define MAXZ (1LL<<22)
bool turnup(int i,int p1,int p2,int p3) //p1>p2>p3
{
LL y1=FZ(i,p1);
LL x1=sum[p1];
LL y2=FZ(i,p2);
LL x2=sum[p2];
LL y3=FZ(i,p3);
LL x3=sum[p3];
if((x2-x3)*(y1-y2)>(x1-x2)*(y2-y3))return ;
else return ;
}
int main()
{
while(scanf("%d%d",&n,&m)&&(n||m))
{
memset(sum,,sizeof sum);
memset(w,,sizeof w);
m++;
for(int i=;i<=n;i++)
{scanf("%d",&num[i]);
sum[i]=sum[i-]+num[i];
w[i]=w[i-]+sum[i-]*num[i];
}
for(int i=;i<=n;i++)
f[][i]=w[i];
for(int i=;i<=m;i++)
{
//f[i-1][i-1]=0;
head=tail=;
que[tail++]=i-;
for(int j=i;j<=n;j++)
{
while(head<tail-&&FZ(i,que[head+])-FZ(i,que[head])<sum[j]*(sum[que[head+]]-sum[que[head]]))head++;
int k=que[head];
f[i][j]=f[i-][k]+w[j]-w[k]-sum[k]*(sum[j]-sum[k]);
while(head<tail-&&turnup(i,j,que[tail-],que[tail-])==)
tail--;
que[tail++]=j;
}
}
/*
for(int i=1;i<=m;i++)
{for(int j=1;j<=n;j++)
printf("%I64d ",f[i][j]);
printf("\n");
}
*/
printf("%I64d\n",f[m][n]);
}
}

本题也可以用平行四边形优化。

f[i][j]=f[i-1][k]+w[k+1,j]

w[k+1,j]很明显满足区间包含性质和平行四边形性质,所以f[i][j]也满足平行四边形性质,所以设s[i][j]表示f[i][j]的最佳决策点。s[i-1][j]<=s[i][j]<=s[i][j+1]。

从常识角度来思考,也是比较好想的。

如果数组元素不变,分段数增加,肯定分界点会往两边扩展,若分段数减少,则分界点会往中间靠拢,所以s[i][j]<=s[i+1][j]

如果分段数不变,数的个数增加(右边补充进来),分界点应该往右微调;如果数的个数减少(从右边剔除),分界点应该往左微调,所以有s[i][j-1]<=s[i][j]

所以s[i-1][j]<=s[i][j]<=s[i][j+1]

 #include<iostream>
#include<cstring>
#include<cstdio>
#define MAXN 1005
#define MAXM 1005
#define LL long long int
#define min(a,b) ((a)<(b)?(a):(b))
LL f[MAXN][MAXM],sum[MAXN],w[MAXN],s[MAXN][MAXM];
int num[MAXN],t,n,m;
using namespace std;
void pre()
{
for(int i=;i<=n;i++)
sum[i]=sum[i-]+num[i];
for(int i=;i<=n;i++)
w[i]=w[i-]+sum[i-]*num[i];
}
int main()
{
while(scanf("%d%d",&n,&m)&&(n||m))
{
m++;
for(int i=;i<=n;i++)
scanf("%d",&num[i]);
memset(f,0x3f,sizeof f);
pre();
for(int i=;i<=n;i++)
{for(int j=i;j<=n;j++)
s[i][j]=i-;
}
for(int i=;i<=n;i++)
s[i][m+]=i-;
for(int i=;i<=n;i++)
f[i][i]=;
for(int j=;j<=n;j++)
f[j][]=w[j]; for(int i=;i<=n;i++)
for(int j=min(m,i);j>=;j--)
{
for(int k=s[i][j+];k>=s[i-][j];k--)
{
LL temp=f[k][j-]+w[i]-w[k]-sum[k]*(sum[i]-sum[k]);
if(f[i][j]>temp)
{f[i][j]=temp;
s[i][j]=k;
}
}
}
printf("%I64d\n",f[n][m]);
}
}

HDU2829的更多相关文章

  1. HDU2829 Lawrence —— 斜率优化DP

    题目链接:https://vjudge.net/problem/HDU-2829 Lawrence Time Limit: 2000/1000 MS (Java/Others)    Memory L ...

  2. HDU2829 Lawrence(斜率优化dp)

    学了模板题之后上网搜下斜率优化dp的题目,然后就看到这道题,知道是斜率dp之后有思路就可以自己做不出来,要是不事先知道的话那就说不定了. 题意:给你n个数,一开始n个数相邻的数之间是被东西连着的,对于 ...

  3. HDU-2829 Lawrence (DP+四边形不等式优化)

    题目大意:有n个敌方军火库呈直线排列,每个军火库有一个值vi,并且任意相邻的两个库之间都有通道相连.对于任意一条连起来的军火库链,它对我方的威胁可以用函数w(i,j)表示为:w(i,j)=vi*sum ...

  4. hdu2829 Lawrence

    题目链接:戳我 朴素DP:\(dp[i][j]=dp[i-1][k]+cost[k+1][j]\) 其中dp[i][j]表示炸第i次的时候,处理到前j个的最小值是多少.cost[i][j]表示的是i, ...

  5. hdu2829 四边形优化dp

    Lawrence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total S ...

  6. [HDU2829] Lawrence [四边形不等式优化dp]

    题面: 传送门 思路: 依然是一道很明显的区间dp 我们设$dp\left[i\right]\left[j\right]$表示前$j$个节点分成了$i$块的最小花费,$w\left[i\right]\ ...

  7. 斜率优化板题 HDU2829 Lawrence

    题目大意:给定一个长度为nnn的序列,至多将序列分成m+1m+1m+1段,每段序列都有权值,权值为序列内两个数两两相乘之和.求序列权值和最小为多少? 数据规模:m<=n<=1000.m&l ...

  8. 单调队列 && 斜率优化dp 专题

    首先得讲一下单调队列,顾名思义,单调队列就是队列中的每个元素具有单调性,如果是单调递增队列,那么每个元素都是单调递增的,反正,亦然. 那么如何对单调队列进行操作呢? 是这样的:对于单调队列而言,队首和 ...

  9. DP总结 ——QPH

    常见优化 单调队列 形式 dp[i]=min{f(k)} dp[i]=max{f(k)} 要求 f(k)是关于k的函数 k的范围和i有关 转移方法 维护一个单调递增(减)的队列,可以在两头弹出元素,一 ...

随机推荐

  1. Windows下Nginx+Tomcat整合的安装与配置

    原帖:http://zyjustin9.iteye.com/blog/2017394 相信很多人都听过nginx,这个小巧的东西慢慢地在吞食apache和IIS的份额.那究竟它有什么作用呢?可能很多人 ...

  2. 310. Minimum Height Trees

    For a undirected graph with tree characteristics, we can choose any node as the root. The result gra ...

  3. Android加载网络图片的工具类

    ImageView加载网络的图片 HttpUtil.java package com.eiice.httpuimagetils; import java.io.ByteArrayOutputStrea ...

  4. 转ORA-28002: the password will expire within 7 days 解决方法

    最后一步要改密码,否则还会报错. 1. 查看用户的profile设置: SELECT username,profile FROM dba_users; 一般用户的profile设置都为DEFAULT. ...

  5. ArrayList线程不安全

    ArrayList线程不安全分析 http://wsmajunfeng.iteye.com/blog/1493941   一个 ArrayList ,在添加一个元素的时候,它可能会有两步来完成:1. ...

  6. Win10如何设置相关性

    为什么要设置相关性? 有一些老的游戏或者程序,没有针对多核cpu进行优化,运行的时候会出现卡顿,这个时候需要通过相关性的设置,让程序只使用一个cpu核心. 怎么设置相关性? win10以前的系统直接打 ...

  7. 配置Apache将自己的电脑做服务器使局域网内的电脑访问自己的主机

    很多的朋友都想把自己的电脑打造为服务器使别人能够访问.比如说你自己写了一网站,只能自己通过localhost访问或127.0.0.1访问.但是怎么让别人的电脑也能访问呢?来看看自己写的网站.现在我来讲 ...

  8. java定时框架:表达式设置

    Quartz中时间表达式的设置-----corn表达式 (注:这是让我看比较明白的一个博文,但是抱歉,没有找到原作者,如有侵犯,请告知) 时间格式: <!-- s m h d m w(?) y( ...

  9. 斯坦福大学Andrew Ng教授主讲的《机器学习》公开课观后感[转]

    近日,在网易公开课视频网站上看完了<机器学习>课程视频,现做个学后感,也叫观后感吧. 学习时间 从2013年7月26日星期五开始,在网易公开课视频网站上,观看由斯坦福大学Andrew Ng ...

  10. awk命令拷屏

    如果不指明采取什么动作,awk默认打印出所有浏览出的记录,与{print $}是一样的 模式和动作两者是可选的,如果没有模式,则action应用到全部记录,如果没有action,则输出匹配全部记录. ...