码迷,mamicode.com
首页 > 其他好文 > 详细

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

时间:2018-01-02 21:27:38      阅读:143      评论:0      收藏:0      [点我收藏+]

标签:col   its   不等式   c++   i+1   log   bit   四边形不等式   bsp   

题目描述

  有一排石子,共n 堆。现要将石子有次序地合并成一堆。规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分。试设计一个算法,计算出将n堆石子合并成一堆的最小得分。

题解

  首先由直接动态规划的方法来做,即 

for(int i=1;i<=n;i++)
    for(int j=i;j<=n;j++)
        for(int k=i;k<=j;k++)
            {
               f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+cost[j]-cost[i-1]);
        
}   

  但是如果N的值超过了3000的话,这个算法就明显会爆炸的,所以我们应当采取一定的优化,经过计算我们可以发现这个题目是满足四边形不等式的,这里所用的优化呢是四边形不等式优化。

  我们定义阶段为区间长度len,状态为f[i][j]合并i到j的最小费用。

  注意:因为我们的阶段决定了,在计算s[i][j]时,s[i][j-1]和s[i+1][j]都已经计算出来了

代码

//FZOJ1555 合并石子(求最小值)四边形不等式优化 
#include<bits/stdc++.h>
using namespace std;
int f[101][101],s[101][101],a[101],sum[101],q;
int main()
{
    int i,j,k,n,len,q;
    scanf("%d",&n);
    memset(sum,0,sizeof(sum));
    memset(f,60,sizeof(f));
    memset(s,0,sizeof(s));
    for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }    
    for(i=1;i<=n;i++)
        {
            f[i][i]=0;
            s[i][i]=i;
        }
    for(len=1;len<n;len++)
        for(i=1;i<=n-len;i++)
            {
                j=i+len;
                q=sum[j]-sum[i-1];
                for(k=s[i][j-1];k<=s[i+1][j];k++)
                    {
                        if(f[i][j]>f[i][k]+f[k+1][j]+q)
                            {
                                f[i][j]=f[i][k]+f[k+1][j]+q;
                                s[i][j]=k;
                            }
                    }
            }
    printf("%d\n",f[1][n]);
    return 0;
}

 

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

标签:col   its   不等式   c++   i+1   log   bit   四边形不等式   bsp   

原文地址:https://www.cnblogs.com/2020pengxiyue/p/8178818.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!