• nyoj 题目737 合并石子(一)


    石子合并(一)

    时间限制:1000 ms  |  内存限制:65535 KB
    难度:3
     
    描述
        有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

    据说这是一个区间dp问题
    代码如下
     1 #include <cstdio>
     2 #include <cstring>
     3 #include <algorithm>
     4 #include <iostream>
     5 #define INF 999999999
     6 int dp[210][210];
     7 int stone[210];
     8 int sum[210];
     9 
    10 using namespace std;
    11 
    12 int main(int argc, char const *argv[])
    13 {
    14     int n;
    15     while(scanf("%d",&n) != EOF) {
    16         memset(dp, 0, sizeof(dp));
    17         memset(sum, 0, sizeof(sum));
    18         for(int i = 1; i <= n; i++) {
    19             scanf("%d",&stone[i]);
    20             sum[i] = sum[i-1]+stone[i];
    21         }
    22         for(int len = 2; len <= n; len++) {
    23             for(int i = 1; i+len-1<= n; i++) {
    24                 int j = i+len-1;
    25                 dp[i][j] = INF;
    26                 for(int k = i; k < i+len-1;k++) {
    27                     dp[i][j] = min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);
    28                 }
    29             }
    30         }
    31         printf("%d
    ", dp[1][n]);
    32     }
    33     return 0;
    34 }

    dp[i][j]表示在区间i到j内合并所需要的最小代价

  • 相关阅读:
    【LOJ #2290】「THUWC 2017」随机二分图(状压DP)
    【LOJ #2136】「ZJOI2015」地震后的幻想乡(状压DP)
    【CSP-S 2019模拟】题解
    异步编程补漏
    Git(七) 查漏补缺
    ES6(二) let const
    ES6(一) 数组
    JS判断对象是否存在
    Git(六)
    Git(五)
  • 原文地址:https://www.cnblogs.com/jasonJie/p/6095353.html
Copyright © 2020-2023  润新知