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

3002 石子归并 3

参考 http://it.dgzx.net/drkt/oszt/zltk/yxlw/dongtai3.htm

 

 时间限制: 1 s
 空间限制: 256000 KB
 题目等级 : 钻石 Diamond
 
 
 
题目描述 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

样例输出 Sample Output

18

数据范围及提示 Data Size & Hint

数据范围相比“石子归并” 扩大了

 

/*
据说是一道四边形不等式优化dp的典型例题,然而我一知半解的并没有搞懂23333
只能抄下来背过......
还据说有一个GarsiaWachs算法专门解决这个问题,并且思想特别好懂 
然而我这么若没有看懂代码......
唉!先存着以后再看吧。 
*/
#include<cstdio>
#include<cstring>
#define N 3010

using namespace std;
int n,s[N],f[N][N],b[N][N];
int main()
{
    scanf("%d",&n);
    for(int i=1;i<=n;i++) 
        scanf("%d",&s[i]),s[i]+=s[i-1];
    for(int i=1;i<=n;i++) 
        b[i][i]=i;
    for(int j=2;j<=n;j++)
        for(int i=j-1;i>>0&&j-i<n;i--)
        {
            f[i][j]=0x7fffffff;
            for(int k=b[i][j-1];k<=b[i+1][j];k++)
            {
                if(f[i][j]>f[i][k]+f[k+1][j]+s[j]-s[i-1]){
                    f[i][j]=f[i][k]+f[k+1][j]+s[j]-s[i-1];
                    b[i][j]=k;
                }
            }
        }
    printf("%d\n",f[1][n]);
    return 0;
}
我不会啊我不会

 

posted @ 2017-01-28 16:48  安月冷  阅读(252)  评论(0编辑  收藏  举报