zoukankan      html  css  js  c++  java
  • NYOJ737石子合并(二)-(区间dp)

    题目描述:

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

    输入描述:

    有多组测试数据,输入到文件结束。
    每组测试数据第一行有一个整数n,表示有n堆石子。
    接下来的一行有n(0< n <200)个数,分别表示这n堆石子的数目,用空格隔开

    输出描述:

    输出总代价的最小值,占单独的一行

    样例输入:

    3
    1 2 3
    7
    13 7 8 16 21 4 18

    样例输出:

    9
    239
    #include<stdio.h>
    #include<iostream>
    #include<algorithm>
    #include<cstring>
    #include<math.h>
    #include<string>
    #define ll long long
    #define inf 0x3f3f3f3f
    using namespace std;
    
    int a[205];
    int sum[205][205];
    int dp[205][205];
    int main()
    {
        int n;
        while(scanf("%d",&n)!=EOF)
        {
            memset(sum,0,sizeof(sum));
            memset(dp,inf,sizeof(dp));
            for(int i=1;i<=n;i++)
            {
                scanf("%d",&a[i]);
                sum[i][i]=a[i];
                dp[i][i]=0;///递推式中如果只有两个石子就是0+0+sum[i]=[j]
            }
            for(int len=2;len<=n;len++)
            {
                for(int i=1;i+len-1<=n;i++)
                {
                    int j=i+len-1;
                    sum[i][j]=sum[i][j-1]+sum[j][j];///表示i到j的石子的总重量
    
                    for(int k=i+1;k<=j;k++)
                        dp[i][j]=min(dp[i][j],dp[i][k-1]+dp[k][j]+sum[i][j]);
                    ///以k-1为分界,之前搬成两堆的体力 + 合并两堆的体力
                }
            }
            printf("%d
    ",dp[1][n]);
        }
        return 0;
    }
  • 相关阅读:
    Chromium GN构建工具的使用
    cef 不更新编译
    Debugging SSL on Linux
    chromium url 请求流程
    mim
    qt打包发布问题 缺失qt动态库
    qmake生成pro的make总失败。但是qt creator里面是好的
    qt 与 x11 头文件同时引用
    Ubuntu16安装GTK+2.0教程
    gcc编译静态库到自己的程序 解决在不同linux下因libc版本问题而不能运行 版本兼容问题
  • 原文地址:https://www.cnblogs.com/shoulinniao/p/10595690.html
Copyright © 2011-2022 走看看