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

题目描述

  有一排石子,共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;
}

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

时间: 2024-10-13 19:36:10

合并石子 四边形不等式优化的相关文章

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

该来的总是要来的———————— 经典问题,石子合并. 对于 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

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

题目大意很简单,和普通的石子合并过程没有区别,只是花费变成了一个多项式,若连续的任意个石子权值和为x,那么代价变为F(x) = sigma(a[i] * x^i),求将n堆石子合并为一队的最小花费. 对于暴力的做法,复杂度是O(n^3)的,所以要优化 我们知道当a, b, c, d(a <= b < c <= d)当有cost[a][c] + cost[b][d] <= cost[a][d] + cost[b][c] 时,我们称其满足四边形不等式,设p[i][j]表示当区间[i,

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

好方啊马上就要区域赛了连DP都不会QAQ 毛子青<动态规划算法的优化技巧>论文里面提到了一类问题:石子合并. n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分. 求出将n堆石子合并成一堆的最小得分和最大得分以及相应的合并方案. 设m[i,j]表示合并d[i..j]所得到的最小得分. 状态转移方程: 总的时间复杂度为O(n3). [优化方案] 四边形不等式: m[i,j]满足四边形不等式 令s[i,j]=max{k | m[

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

题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1].问安排怎样的合并顺序,能够使得总合并代价达到最小. 输入描述 Input Description 第一行一个整数n(n≤3000) 第二行n个整数w1,w2...wn(wi≤3000) 输出描述 Output Description 一个整数表示最小合并代价 样例输入 Sample Input 4 4 1 1 4 样例输出 S

[51nod 1022] 石子归并v2 [dp+四边形不等式优化]

题面: 传送门 思路: 加强版的石子归并,现在朴素的区间dp无法解决问题了 首先我们破环成链,复制一条一样的链并粘贴到原来的链后面,变成一个2n长度的序列,在它上面dp,效率O(8n^3) 显然是过不了的,需要优化 注意:dp的转移如下:dp[i][j]=min(dp[i][k]+dp[k+1][j]+sum(i,j)),其中sum(i,j)表示i到j的价值和,满足区间单调性 因此dp[i][j]也满足区间单调性,可以用四边形不等式优化 我们令s[i][j]等于让dp[i][j]取最小值的那个K

四边形不等式优化

四边形不等式优化条件(转自这里) 在动态规划中,经常遇到形如下式的转台转移方程: m(i,j)=min{m(i,k-1),m(k,j)}+w(i,j)(i≤k≤j)(min也可以改为max) 上述的m(i,j)表示区间[i,j]上的某个最优值.w(i,j)表示在转移时需要额外付出的代价.该方程的时间复杂度为O(N^3). 下面我们通过四边形不等式来优化上述方程,首先介绍什么是"区间包含的单调性"和"四边形不等式" (1)区间包含的单调性:如果对于i≤i'<j≤

[dp专题-四边形不等式优化]51nod 1022

? 1021?石子归并?V1 N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价.计算将N堆石子合并成一堆的最小代价. ? 例如: 1 2 3 4,有不少合并方法 1 2 3 4 => 3 3 4(3) => 6 4(9) => 10(19) 1 2 3 4 => 1 5 4(5) => 1 9(14) => 10(24) 1 2 3 4 => 1 2 7(7) => 3 7(1

区间dp+四边形不等式优化

区间dp+四边形优化 luogu:p2858 题意 给出一列数 \(v_i\),每天只能取两端的数,第 j 天取数价值为\(v_i \times j\),最大价值?? 转移方程 dp[i][j] :n天卖掉i..j货物的收益 dp[begin][end]=max(dp[begin][end-1]+value[end]*(n-len+1) ,dp[begin+1][end]+value[begin]*(n-len+1)); 注意理解 代码 递推形式 #include<bits/stdc++.h>

动态规划之四边形不等式优化

四边形不等式 设函数\(w(x,y)\)是定义在\(Z\)上的函数,若对于任意\(a,b,c,d \in Z\),其中\(a\leq b \leq c \leq d\), 都有\(w(a,d)+w(b,c)\ge w(a,c)+w(b,d)\),则称函数\(w\)满足四边形不等式 推论: 设函数\(w(x,y)\)是定义在\(Z\)上的函数,若对于任意\(a,b \in Z\),其中\(a<b\), 都有\(w(a,b+1)+w(a+1,b) \ge w(a,b)+w(a+1,b+1)\),则函