codevs1048 石子归并

题目描述 Description

有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1]。问安排怎样的合并顺序,能够使得总合并代价达到最小。

输入描述 Input Description

第一行一个整数n(n<=100)

第二行n个整数w1,w2...wn  (wi <= 100)

输出描述 Output Description

一个整数表示最小合并代价

样例输入 Sample Input

4

4 1 1 4

样例输出 Sample Output

18

思路:

以区间长度划分阶段

ps.如果是任意两堆直接贪心,越是先合并的计算次数就越多

代码:

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>

using namespace std;
const int maxn = 200,maxnum = 10000000;
int n,j,value[maxn],sum[maxn],dp[maxn][maxn];
int main(){
    cin>>n;
    for(int i = 1;i <= n;i++){
        cin>>value[i];
        sum[i]= sum[i-1] + value[i];
    }
    for(int l = 2;l <= n;l++){
        for(int i = 1;i <= n - l + 1;i++){
            j = i + l - 1;
            dp[i][j] = maxnum;
            for(int k = i;k < j;k++)
               dp[i][j] = min(dp[i][j],dp[i][k] + dp[k+1][j] + sum[j] - sum[i-1]);
        }
    }
    cout<<dp[1][n];
    return 0;
}
时间: 2024-12-12 17:12:02

codevs1048 石子归并的相关文章

【日常学习】【区间DP】codevs1048 石子归并题解

题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1].问安排怎样的合并顺序,能够使得总合并代价达到最小. 输入描述 Input Description 第一行一个整数n(n<=100) 第二行n个整数w1,w2...wn  (wi <= 100) 输出描述 Output Description 一个整数表示最小合并代价 样例输入 Sample Input 4 4 1 1 4 样

[codevs1048]石子归并&amp;&amp;[codevs2102][洛谷P1880]石子归并加强版

codevs1048: 题目大意:有n堆石子排成一列,每次可合并相邻两堆,代价为两堆的重量之和,求把他们合并成一堆的最小代价. 解题思路:经典区间dp.设$f[i][j]$表示合并i~j的石子需要的最小代价.则有$f[i][j]=min(f[i][k]+f[k+1][j]+\sum\limits _{l=i}^{j}a[l])$,时间复杂度$O(n^3)$. C++ Code: #include<cstdio> #include<cstring> using namespace s

[codevs1048]石子归并 区间dp经典

初始化:f[i][i]置成i,其余为0 三重循环用f[i][j]+f[k][k]更新f[i][j] 最后用一个三重循环更新ans数组,记得提前置成最大值 var w:array[0..105]of longint; f,sum:array[0..105,0..105]of longint; i,n,j,x,y,k:longint; function min(x,y:longint):longint; begin if x>y then exit(y) else exit(x); end; beg

3002 石子归并 3

时间限制: 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) 输出描述 Outpu

1048 石子归并

1048 石子归并 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 黄金 Gold 题目描述 Description 有n堆石子排成一列,每堆石子有一个重量w[i], 每次合并可以合并相邻的两堆石子,一次合并的代价为两堆石子的重量和w[i]+w[i+1].问安排怎样的合并顺序,能够使得总合并代价达到最小. 输入描述 Input Description 第一行一个整数n(n<=100) 第二行n个整数w1,w2...wn  (wi <= 100) 输出描述 Output Des

石子归并(dp)

石子归并 Time Limit: 1 Sec  Memory Limit: 128 MB Submit: 89  Solved: 22 [Submit][Status][Web Board] Description 现在有n堆石子,第i堆有ai个石子.现在要把这些石子合并成一堆,每次只能合并相邻两个,每次合并的代价是两堆石子的总石子数.求合并所有石子的最小代价. Input 第一行包含一个整数T(T<=50),表示数据组数. 每组数据第一行包含一个整数n(2<=n<=100),表示石子的

AC日记——石子归并 51nod 1021

石子归并 思路: 经典动态规划——归并类问题: 我们把状态划为n个,即1-n的n个长度为n个状态: 那么,每个长度为i的状态都可以由i-1个长度为i-1的状态推出: 所以,dp转移方程: dp[i][j]=min(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]); 来,上代码: #include <cstdio> #include <cstring> #include <iostream> #include <algori

codevs 2102 石子归并2

传送门 2102 石子归并 2 时间限制: 10 s 空间限制: 256000 KB 题目等级 : 黄金 Gold 题目描述 Description 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分.试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得分. 输入描述 Input Description 数据的第1行试正整数N,1≤N≤100,表示有N堆石子.第2行有N个数,分别表示每堆石子的

51Nod - 1021 石子归并

51Nod -  1021 石子归并 N堆石子摆成一条线.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的代价.计算将N堆石子合并成一堆的最小代价. 例如: 1 2 3 4,有不少合并方法 1 2 3 4 => 3 3 4(3) => 6 4(9) => 10(19) 1 2 3 4 => 1 5 4(5) => 1 9(14) => 10(24) 1 2 3 4 => 1 2 7(7) => 3 7