zoukankan      html  css  js  c++  java
  • 区间DP——石子合并问题

    述    有N堆石子排成一排,每堆石子有一定的数量。现要将N堆石子并成为一堆。合并的过程只能每次将相邻的两堆石子堆成一堆,每次合并花费的代价为这两堆石子的和,经过N-1次合并后成为一堆。求出总的代价最小值。

     
    输入
    有多组测试数据,输入到文件结束。
    每组测试数据第一行有一个整数n,表示有n堆石子。
    接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开
    输出
    输出总代价的最小值,占单独的一行
    样例输入
    3
    1 2 3
    13 7 8 16 21 4 18
    大意:如题意:用一个k记录从是第几次,然后i从1开始到n-k-1结束,j=i+l-1表示,插入m,所以要sum[j]-sum[i-1]
    O(n^3)代码
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    const int MAX = 1000;
    const int inf = 9999999;
    int dp[MAX][MAX],ans[MAX],sum[MAX];
    int main()
    {
        int n;
        scanf("%d",&n);
        memset(dp,0,sizeof(dp));
        sum[0] = 0;
        for(int i = 1; i <= n ; i++){
            scanf("%d",&ans[i]);
            sum[i] = sum[i-1] + ans[i];
        }
        int k,i,j;
        for(int k = 2; k <= n ; k++){
            for(int i = 1; i <= n - k + 1;i++){
                j = i + k - 1;
               dp[i][j] = inf;
               for(int m = i; m < j ; m++){
                    dp[i][j] = min(dp[i][j],dp[i][m]+dp[m+1][j]+sum[j]-sum[i-1]);
               }
            }
        }
       printf("%d
    ",dp[1][n]);
      return 0;
    }
    View Code

    可以用平行四边形优化,即用一个数组s来存储每个最优位置。

        #include<cstdio>
        #include<cstring>
        #include<algorithm>
        using namespace std;
        const int MAX = 1000;
        const int inf = 9999999;
        int dp[MAX][MAX],ans[MAX],sum[MAX],s[MAX][MAX];
        int main()
        {
            int n;
            scanf("%d",&n);
            memset(dp,0,sizeof(dp));
            sum[0] = 0;
            for(int i = 1; i <= n ; i++){
                scanf("%d",&ans[i]);
                sum[i] = sum[i-1] + ans[i];
                s[i][i] = i;
            }
            int k,i,j;
            for(int k = 2; k <= n ; k++){
                for(int i = 1; i <= n - k + 1;i++){
                    j = i + k - 1;
                   dp[i][j] = inf;
                   for(int m = s[i][j-1]; m <= s[i+1][j];m++){
                       if(dp[i][j] > dp[i][m]+dp[m+1][j]+sum[j]-sum[i-1]){
                           dp[i][j] = dp[i][m]+dp[m+1][j]+sum[j]-sum[i-1];
                           s[i][j] = m;
                     }
                   }
                }
            }
           printf("%d
    ",dp[1][n]);
          return 0;
        }
    View Code
  • 相关阅读:
    ecshop学习1
    ecshop安装
    PHP文本操作
    tornado入门1
    windows下WAMP php5.x redis扩展
    Linux下php安装Redis扩展
    在Linux上安装SVN服务
    Application runtime path "/opt/lampp/htdocs/yii/test/protected/runtime" is not valid. 错误
    CDbConnection failed to open the DB connection: could not find driver错误的处理
    PHP框架 Yii framework 用yiic命令时提示“php.exe”不是内部或外部命令
  • 原文地址:https://www.cnblogs.com/zero-begin/p/4345143.html
Copyright © 2011-2022 走看看