题目大意:在一个一维坐标轴上有v个(1<=v<=300)村庄,要建p(1<=p<=30)个邮局,每个村庄都到最近的邮局,要求最小的距离和。

     四边形不等式,据说黑书上写得很高深。

   描述是这样的:令(a<=b<=c<=d,i<=k<j),若w[a][c]+w[b][d]<=w[a][d]+w[b][c],m[i][j]=min OR max{m[i][k]+m[k+1][j]+w[i][j]}则m[a][c]+m[b][d]<=m[a][d]+m[b][c]。

   对于这个式子,个人觉得没必要深究,读者读读题目就应该知道自己要求的m[i][j]定义,取min或者max。我也不会证明,只能弱弱感受到是这么回事。(毕竟那些都不重要,因为不涉及最后求解结果)

     最重要的是这个式子,假设s[i][j]是对应取到m[i][j]的最优解(s当然是solution的意思了,关于解的描述要细细考虑,因为它并不用是一种很确切的表示,只需要是一个关键的量就可以)。PS:我觉得,我要是不解释这个关键量,很多人肯定会黑我的,但是我真的不知道怎么表达。看代码中的注解吧。

    四边形不等式最大优化是s[i][j]一定介于s[k=i-1 或者 k=i+1][j]、s[i][j+1]之间。(也有很多博客上写成s[i-1][j]<=s[i][j]<=s[i][j+1])这样对于我们搜索关于s[i][j]的值时范围大大缩短了。对于s[i][max_(i)]可以用我们通常容易想到的dp方程线性效率解决。而s[i][1]到s[i][max_(i)-1]这一段的解,总共的效率可以缩短到线性。 

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int infinity=(-)^(<<);
const int V=;
const int P=;
int dp[V][P], s[V][P];
int atx[V],sum[V];
inline int setat(int i,int j){
return (i+j)>>;
}
int move_all(int fr,int ba){
//printf("move from %d to %d = %d\n",fr,ba,(sum[ba]-sum[fr])-atx[fr]*(ba-fr));
return (sum[ba]-sum[fr])-atx[fr]*(ba-fr);
}
int S(int i,int j){
int pos=setat(i,j);
int ret=move_all(pos,j);
ret += (atx[pos]-atx[i])*(pos-i+)-move_all(i,pos);
return ret;
}
int DP(int v,int p){
sort(atx+,atx++v);
for(int i=v;i>=;i--) atx[i]-=atx[];
for(int i=;i<=v;i++) sum[i]=sum[i-]+atx[i];
//for(int i=1;i<=v;i++) printf("%3d ",atx[i]); printf("\n");
for(int i=;i<=v;i++)
dp[i][]=S(,i), s[i][]=setat(,i); //printf("1 --> %4d, %d\n",i,dp[i][1]);
if(p >= )
for(int i=;i<=v;i++){
int maxj=min(i,p);
dp[i][maxj]=infinity;
for(int k=maxj-;k<i;k++)
if(dp[k][maxj-]+S(k+,i) < dp[i][maxj])
dp[i][maxj]=dp[k][maxj-]+S(k+,i), s[i][maxj]=k;
//printf("dp[%d][%d] = %d, s[i][maxj] = %d\n",i,maxj,dp[i][maxj],s[i][maxj]);
for(int j=maxj-;j>=;j--){
dp[i][j]=infinity;
for(int k=s[i-][j];k<=s[i][j+];k++)
if(dp[k][j-]+S(k+,i) < dp[i][j]){
dp[i][j]=dp[k][j-]+S(k+,i);
s[i][j]=k;
}
}
}
return dp[v][p];
}
int main()
{
int v,p;
while(scanf("%d%d",&v,&p) != EOF){
for(int i=;i<=v;i++)
scanf("%d",&atx[i]);
printf("%d\n",DP(v,p));
}
return ;
}

  个人觉得,在很多性质上,它跟斜率优化dp很像,甚至可以说斜率优化dp是最特殊的一类四边形不等式dp。斜率优化的dp中,最优化只根一个值有关,因为它保持后来无关单调。四边形不等式,把最优解的可选方案限制起来。

  我也是四边形不等式的初学者,希望路过的大牛不吝赐教。

poj1160的更多相关文章

  1. 【poj1160】 Post Office

    http://poj.org/problem?id=1160 (题目链接) 题意 按照递增顺序给出一条直线上坐标互不相同的n个村庄,要求从中选择p个村庄建立邮局,每个村庄使用离它最近的那个邮局,使得所 ...

  2. 石子合并(四边形不等式优化dp) POJ1160

    该来的总是要来的———————— 经典问题,石子合并. 对于 f[i][j]= min{f[i][k]+f[k+1][j]+w[i][j]} From 黑书 凸四边形不等式:w[a][c]+w[b][ ...

  3. [poj1160][IOI2000]Post Office【动态规划】

    传送门 https://vjudge.net/problem/POJ-1160#author=SCU2018 题目描述 在一条水平的公路上建有n个小屋,两个小屋间的距离是它们的横坐标之差的绝对值.保证 ...

  4. 区间DP POJ1160村庄邮局问题

    POJ1160 题目大意:一系列村庄在一维坐标系上有序的排列,建设p个邮局,问各个村庄到邮局的最短距离和. 线性区间DP问题 dp数组的值为最短/最优距离 村庄和邮局为限制 dp[i][j]表示前i个 ...

  5. DP---基本思想 具体实现 经典题目 POJ1160 POJ1037

    POJ1160, post office.动态规划的经典题目.呃,又是经典题目,DP部分的经典题目怎就这么多.木有办法,事实就这样. 求:在村庄内建邮局,要使村庄到邮局的距离和最小. 设有m个村庄,分 ...

  6. IOI2000 Post Office (POJ1160)

    前言 昨天XY讲课!讲到这题!还是IOI的题!不过据说00年的时候DP还不流行. 题面 http://poj.org/problem?id=1160 分析  § 1 中位数 首先我们考虑,若有x1 & ...

  7. POJ1160 Post Office[序列DP]

    Post Office Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 18680   Accepted: 10075 Des ...

  8. poj1160 dp

    //Accepted 564 KB 63 ms //和hdu1227一样 //dp[i][j]=min(dp[i][j],dp[k][j-1]+cost[k+1][i]) //初始化条件,dp[0][ ...

  9. poj1160 post office

    题目大意:有n个乡村,现在要建立m个邮局,邮局只能建在乡村里.现在要使每个乡村到离它最近的邮局距离的总和尽量小,求这个最小距离和. n<300,p<30,乡村的位置不超过10000. 分析 ...

随机推荐

  1. (转)轻量级数据库 SQLite

    SQLite Expert – Personal Edition SQLite Expert 提供两个版本,分别是个人版和专业版.其中个人版是免费的,提供了大多数基本的管理功能. SQLite Exp ...

  2. 初识动画animation

    工作半年了,基本没怎么用到动画,现在对已学到的动画做一个总结(真的非常非常基础啊啊啊),准备之后再慢慢研究一下动画(有好的教程可以推荐给我咩~~). animation animation:mymov ...

  3. UVA 1617 Laptop

    题意: 有n条长度为1的线段,确定他们的起点,必须是整数,使得第i条线段在[ri,di]之间.最后输出空隙的最小值 分析: 原始数据排序,排序的规则是先按照右端点排序,右端点相同的情况下,再按照左端点 ...

  4. ViewState存储到服务器

    把viewstate保存在服务器上 将ViewState持久化保持在服务器端的代码,这样ViewState不占用网络带宽,因此其存取只是服务器的磁盘读取时间.并且它很小,可以说是磁盘随便转一圈就能同时 ...

  5. maven简单工具命令

    (一)聚合项目的创建//创建父项目mvn archetype:create -DgroupId=com.ztesoft.resmaster -DartifactId=lifecycle<pack ...

  6. 【IOS学习基础】NSObject.h学习

    一.<NSObject>协议和代理模式 1.在NSObject.h头文件中,我们可以看到 // NSObject类是默认遵守<NSObject>协议的 @interface N ...

  7. OC 数组

    /*---------------------------创建数组------------------------------*/ //NSArray *array = [[NSArray alloc ...

  8. 图的最短路径问题————树上奶牛(tree.cpp)

    和往常一样,继续从题目引入 树上奶牛 (tree.cpp) [题目描述] 农夫John的奶牛不是住在地上而是住在树上的QWQ. 奶牛之间需要串门,不过在串门之前他们会向John询问距离的大小.可是Jo ...

  9. linux中断--进程上下文和中断上下文

    一.前言 中断发生以后,CPU跳到内核设置好的中断处理代码中去,由这部分内核代码来处理中断.这个处理过程中的上下文就是中断上下文. 为什么可能导致睡眠的函数都不能在中断上下文中使用呢? 首先睡眠的含义 ...

  10. Cannot resolve the collation conflict between "SQL_Latin1_General_CP1_CI_AS" and "Chinese_PRC_CI_AS" in the equal to operation.

    Scenario : 这个问题是我的存储过程中用到临时表时发生的. 应该是sql server 服务器的排序规则 (SQL_Latin1_General_CP1_CI_AS ) 与数据库的排序规则(C ...