zoukankan      html  css  js  c++  java
  • 四边形优化dp

    拿石子合并这题为例

    设mid[i][j]是dp[i][j]的最优解的断点,即它左区间的右端点,那么mid[i][j-1]<=mid[i][j]<=mid[i+1][j],所以在求解dp[i][j]时,枚举k可以只枚举这两个值之间枚举就好,

    程序要先枚举区间长度,在枚举左端点,枚举每个区间长度时,他们的k总是只从1到n,只走一遍,所以这就相当于优化了一层,变成了O(n2)的。

    比如len长度为3时,dp[1][3]只会枚举mid[1][2]-mid[2][3],如上。然后dp[2][4]时,枚举mid[2][3]-mid[3][4]。以此类推。

    数据变大了,n^3过不了,考虑四边形优化

    code:

    #include <iostream>
    #include <cstdio>
    using namespace std;
    #define M 3003
    #define INF 0x7fffffff
    int n,f[M][M],sum[M][M],st[M],mid[M][M];
    int main() {
        cin>>n;
        for(int i=1; i<=n; i++)
            scanf("%d",&st[i]);
    
        for(int i=1; i<=n; i++) {
            f[i][i]=0;
            mid[i][i]=i;
            sum[i][i]=st[i];
            for(int j=i+1; j<=n; j++)
                sum[i][j]=sum[i][j-1]+st[j];
        }
    
        for(int len=2; len<=n; len++) 
        {
            for(int i=1; i<=n-len+1; i++) 
            {
                int j=i+len-1;
                f[i][j]=INF;
                for(int k=mid[i][j-1]; k<=mid[i+1][j]; k++) 
                {
                    if(f[i][j]>f[i][k]+f[k+1][j]+sum[i][j]) 
                    {
                        f[i][j]=f[i][k]+f[k+1][j]+sum[i][j];
                        mid[i][j]=k;
                    }
                }
            }
        }
        printf("%d
    ",f[1][n]);
        return 0;
    }
  • 相关阅读:
    05 库的简单操作
    04 基本的MySQL语句
    03 MySQL安装和基本管理
    02 数据库概述
    01 MySQL入门了解
    Django-组件拾遗
    bootstrap基础讲解
    jQuery练习
    前端基础之Jquery
    15 Django组件-中间件
  • 原文地址:https://www.cnblogs.com/sssy/p/7197743.html
Copyright © 2011-2022 走看看