该来的总是要来的————————

经典问题,石子合并。

  对于 f[i][j]= min{f[i][k]+f[k+1][j]+w[i][j]}

From 黑书

凸四边形不等式:w[a][c]+w[b][d]<=w[b][c]+w[a][d](a<b<c<d)

区间包含关系单调: w[b][c]<=w[a][d](a<b<c<d)

定理1:  如果w同时满足四边形不等式和决策单调性 ,则f也满足四边形不等式

定理2:  若f满足四边形不等式,则决策s满足 s[i][j-1]<=s[i][j]<=s[i+1][j]

定理3: w为凸当且仅当w[i][j]+w[i+1][j+1]<=w[i+1][j]+w[i][j+1]

简要证明:

若w[a][c]+w[b][d]<=w[b][c]+w[a][d],归纳证明f[a][c]+f[b][d]<=f[b][c]+f[a][d]

  设f[a][d]最优决策是在s取到,f[b][c]最优决策在t取到,设s<t,反之同理

  可知a<s<t<c<d

    f[a][c]+f[b][d]<=f[a][s]+f[s+1][c]+w[a][c] + f[b][t]+f[t+1][d]+w[b][d]

            =f[a][s]+f[s+1][c]+w[a][d] + f[b][t]+f[t+1][d]+w[b][c]

           <=f[a][s]+w[a][d]+f[s+1][d] + f[b][t]+w[b][c]+f[t+1][c]         归纳得到 sc+td<sd+tc  起始条件即定理3

           =f[a][d]+f[b][c]

得证.

若f[a][c]+f[b][d]<=f[b][c]+f[a][d],则s[i][j-1]<=s[i][j]<=s[i+1][j]

  仅证s[i][j-1]<=s[i][j],右边同理

  记f_k[i][j]=f[i][k]+f[k+1][j]+w[i][j]

  记s点为[i,j]最优点,t点为[i,j+1]最优点,

  则只需证明 在[i,j+1]决策时, 取s点能够比取在k∈[i,s-1]的点更优即可

    即证明 f_s[i,j+1]<=f_k[i,j+1]

  又因为f_s[i,j]<=f_k[i,j]

     只需证明 0 <= f_k[i,j] - f_s[i,j] <= f_k[i,j+1] - f_s[i,j+1]

      可发现右边即 f_k[i,j] + f_s[i,j+1] <= f_k[i,j+1] + f_s[i,j]

      展开后即: f[k][j] + f[s][j+1] <= f[k][j+1] + f[s][j]

      正是 k<s<j<j+1 的四边形不等式

得证.

一般利用定理3证明凸函数,然后利用定理2的结论 s[i][j-1]<=s[i][j]<=s[i+1][j]

  就能够使得复杂度由O(n^3)降低为O(n^2)

详细证明参见《动态规划算法的优化技巧》--毛子青(会因为论文用i,j,i',j'搞得雾水,但是慢慢推一下就能够出来)

#include <cstdio>
#include <cstring>
#define N 1005
int s[N][N],f[N][N],sum[N],n;
int main()
{
while(scanf("%d",&n)!=EOF)
{
memset(f,,sizeof(f));
sum[]=;
for(int i=; i<=n; i++){
scanf("%d",&sum[i]);
sum[i]+=sum[i-];
f[i][i]=;
s[i][i+]=i;
}
for(int i=; i<=n; i++)
f[i][i+]=sum[i+]-sum[i-]; for(int i=n-; i>=; i--)
for(int j=i+; j<=n; j++)
for(int k=s[i][j-]; k<=s[i+][j]; k++)
if(f[i][j]>f[i][k]+f[k+][j]+sum[j]-sum[i-])
{
f[i][j]=f[i][k]+f[k+][j]+sum[j]-sum[i-];
s[i][j]=k;
} printf("%d\n",f[][n]);
}
return ;
}

值得注意的是:若是求石子合并的最大值,则不能用四边形不等式。可以证明 f[i,j]=max(f[i+1][j],f[i][j-1])+w[i][j]

POJ1160

f[i][j]=max(f[k][j-1]+w[k+1][i])

  其中f[i][j]表示前i个村落有j个邮电局,w[i][j]表示[i,j]区间上安装一个邮电局最短路径和

其中w[i][j]邮电局必然是安装在(i+j)/2(中位数)的村落中,若(i+j)/2不为整数,则中间两个村落都可以。证明可以看《算法导论》

至于四边形不等式,这次,可以直接容易得到 s[i][j-1]<=s[i][j]<=s[i+1][j] 稍微证明下就可以出来,凭感觉都是对的。

#include <cstdio>
#include <cstring>
#define min(x,y) (x>y?y:x)
int v,p,a[305],sum[305],w[305][305],f[305][35],s[305][35];
int main()
{
memset(f,127,sizeof(f));
scanf("%d%d",&v,&p);
for(int i=1; i<=v; i++){
scanf("%d",&a[i]);
sum[i]=a[i]+sum[i-1];
}
for(int i=1; i<=v; i++){
w[i][i]=0;
for(int j=i+1; j<=v; j++){
w[i][j]=sum[j]-sum[(i+j)/2]-sum[(i+j)/2-1]+sum[i-1];
if((i+j)%2!=0) w[i][j]-=a[(i+j)/2];
}
}
for(int i=1; i<=v; i++)
f[i][1]=w[1][i];
for(int j=2; j<=p; j++){
s[v+1][j]=v-1;
for(int i=v; i>=j; i--)
{
for(int k=s[i][j-1]; k<=s[i+1][j]; k++)
if(f[i][j]>f[k][j-1]+w[k+1][i])
{
f[i][j]=f[k][j-1]+w[k+1][i];
s[i][j]=k;
}
}
}
printf("%d",f[v][p]);
return 0;
}

石子合并(四边形不等式优化dp) POJ1160的更多相关文章

  1. [NOI1995]石子合并 四边形不等式优化

    链接 https://www.luogu.org/problemnew/show/P1880 思路 总之就是很牛逼的四边形不等式优化 复杂度\(O(n^2)\) 代码 #include <ios ...

  2. codevs3002石子归并3(四边形不等式优化dp)

    3002 石子归并 3 参考 http://it.dgzx.net/drkt/oszt/zltk/yxlw/dongtai3.htm  时间限制: 1 s  空间限制: 256000 KB  题目等级 ...

  3. hdu 2829 Lawrence(四边形不等式优化dp)

    T. E. Lawrence was a controversial figure during World War I. He was a British officer who served in ...

  4. BZOJ1563/洛谷P1912 诗人小G 【四边形不等式优化dp】

    题目链接 洛谷P1912[原题,需输出方案] BZOJ1563[无SPJ,只需输出结果] 题解 四边形不等式 什么是四边形不等式? 一个定义域在整数上的函数\(val(i,j)\),满足对\(\for ...

  5. 【转】斜率优化DP和四边形不等式优化DP整理

    (自己的理解:首先考虑单调队列,不行时考虑斜率,再不行就考虑不等式什么的东西) 当dp的状态转移方程dp[i]的状态i需要从前面(0~i-1)个状态找出最优子决策做转移时 我们常常需要双重循环 (一重 ...

  6. CF321E Ciel and Gondolas Wqs二分 四边形不等式优化dp 决策单调性

    LINK:CF321E Ciel and Gondolas 很少遇到这么有意思的题目了.虽然很套路.. 容易想到dp \(f_{i,j}\)表示前i段分了j段的最小值 转移需要维护一个\(cost(i ...

  7. 四边形不等式优化DP——石子合并问题 学习笔记

    好方啊马上就要区域赛了连DP都不会QAQ 毛子青<动态规划算法的优化技巧>论文里面提到了一类问题:石子合并. n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的 ...

  8. HDU 2829 Lawrence (斜率优化DP或四边形不等式优化DP)

    题意:给定 n 个数,要你将其分成m + 1组,要求每组数必须是连续的而且要求得到的价值最小.一组数的价值定义为该组内任意两个数乘积之和,如果某组中仅有一个数,那么该组数的价值为0. 析:DP状态方程 ...

  9. POJ 1160 四边形不等式优化DP Post Office

    d(i, j)表示用i个邮局覆盖前j个村庄所需的最小花费 则有状态转移方程:d(i, j) = min{ d(i-1, k) + w(k+1, j) } 其中w(i, j)的值是可以预处理出来的. 下 ...

随机推荐

  1. How do disable paging by swiping with finger in ViewPager but still be able to swipe programmatically?

    The more general extension of ViewPager would bet to create a "SetPagingEnabled" method so ...

  2. Ubuntu实用快捷键

    ALT + TAB: 切换程序窗口Win+w: 显示所有的工作空间,可轻松进行切换 ===== Terminal终端 ===== CTRL + ALT + T: 打开终端 TAB: 自动补全命令或文件 ...

  3. IntelliJ IDEA 15 设置默认浏览器

    一.设置系统默认浏览器 二.设置项目启动默认浏览器

  4. lucas求组合数C(n,k)%p

    Saving Beans http://acm.hdu.edu.cn/showproblem.php?pid=3037 #include<cstdio> typedef __int64 L ...

  5. Amazon Interview Question: Design an OO parking lot

    Design an OO parking lot. What classes and functions will it have. It should say, full, empty and al ...

  6. hdoj 1102 Constructing Roads

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=1102 分析:看到这题给出的都是矩阵形式,就知道了可以用Prim算法求MST. #include <i ...

  7. URAL 1297 Palindrome 最长回文子串

    POJ上的,ZOJ上的OJ的最长回文子串数据量太大,用后缀数组的方法非常吃力,所以只能挑个数据量小点的试下,真要做可能还是得用manacher.贴一下代码 两个小错,一个是没弄懂string类的sub ...

  8. hdu 2717 Catch That Cow(BFS,剪枝)

    题目 #include<stdio.h> #include<string.h> #include<queue> #include<algorithm> ...

  9. HDU 3461 Code Lock(并查集,合并区间,思路太难想了啊)

    完全没思路,题目也没看懂,直接参考大牛们的解法. http://www.myexception.cn/program/723825.html 题意是说有N个字母组成的密码锁,如[wersdfj],每一 ...

  10. HDU 4143 A Simple Problem(枚举)

    题目链接 题意 : 就是给你一个数n,让你输出能够满足y^2 = n +x^2这个等式的最小的x值. 思路 : 这个题大一的时候做过,但是不会,后来学长给讲了,然后昨天比赛的时候二师兄看了之后就敲了, ...