首页 > 其他 > 详细

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

时间:2014-08-01 22:44:12      阅读:461      评论:0      收藏:0      [点我收藏+]

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

 

经典问题,石子合并。

  对于 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)

bubuko.com,布布扣

详细证明参见《动态规划算法的优化技巧》--毛子青(会因为论文用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,127,sizeof(f));
        sum[0]=0;
        for(int i=1; i<=n; i++){
            scanf("%d",&sum[i]);
            sum[i]+=sum[i-1];
            f[i][i]=0;
            s[i][i+1]=i;
        }
        for(int i=1; i<=n; i++)
            f[i][i+1]=sum[i+1]-sum[i-1];

        for(int i=n-2; i>=1; i--)
            for(int j=i+2; j<=n; j++)
                for(int k=s[i][j-1]; k<=s[i+1][j]; k++)
                if(f[i][j]>f[i][k]+f[k+1][j]+sum[j]-sum[i-1])
                {
                    f[i][j]=f[i][k]+f[k+1][j]+sum[j]-sum[i-1];
                    s[i][j]=k;
                }
    
        printf("%d\n",f[1][n]);
    }
    return 0;
}

 

石子合并(四边形不等式优化dp),布布扣,bubuko.com

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

原文:http://www.cnblogs.com/Mathics/p/3885745.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!