zoukankan      html  css  js  c++  java
  • 合并石子 四边形不等式优化

    题目描述

      有一排石子,共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
    ",f[1][n]);
        return 0;
    }
  • 相关阅读:
    CSS选择器
    CSS框模型
    AJAX
    HTML 表单
    二叉树
    词嵌入、word2vec
    双向、深层循环神经网络
    20201012----每天都在进步吗?
    20201012--环境搭建
    20201011--记录一下
  • 原文地址:https://www.cnblogs.com/2020pengxiyue/p/8178818.html
Copyright © 2011-2022 走看看