[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;

        begin
                readln(n);
                for i:=1 to n do
                read(w[i]);
                fillchar(sum,sizeof(sum),0);
                fillchar(f,sizeof(f),0);
                for i:=1 to n do
                for j:=1 to n do
                for k:=i to j do
                inc(sum[i,j],w[k]);

                for i:=n-1 downto 1 do
                for j:=i+1 to n do
                begin
                        f[i,j]:=maxlongint;
                        for k:=i to j do
                        f[i,j]:=min(f[i,j],f[i,k]+f[k+1,j]+sum[i,j])
                end;
                writeln(f[1,n])
        end.

喜欢就收藏一下,vic私人qq:1064864324,加我一起讨论问题,一起进步^-^

时间: 2024-08-24 00:20:08

[codevs1048]石子归并 区间dp经典的相关文章

台州 OJ 2793 石子归并 区间DP

描述 有n堆石子排成一条直线,每堆石子有一定的重量.现在要合并这些石子成为一堆石子,但是每次只能合并相邻的两堆.每次合并需要消耗一定的体力,该体力为所合并的两堆石子的重量之和.问最少需要多少体力才能将n堆石子合并成一堆石子? 输入 输入只包含若干组数据.每组数据第一行包含一个正整数n(2<=n<=100),表示有n堆石子.接下来一行包含n个正整数a1,a2,a3,...,an(0<ai<=100,1<=i<=n). 输出 对应输入的数据,每行输出消耗的体力. dp[i]

【日常学习】【区间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

区间DP经典模型

http://blog.csdn.net/y990041769/article/details/24238547 先附上一个链接 后面有引用的代码 概述 区间 DP:是指在一段区间上进行的一系列动态规划. 对于区间 DP 这一类问题,我们需要计算区间 [1,n] 的答案,通常用一个二维数组 dp 表示,其中 dp[x][y] 表示区间 [x,y]. 有些题目,dp[l][r] 由 dp[l][r-1] 与 dp[l+1][r] 推得; 也有些题目,我们需要枚举区间 [l,r]内的中间点,由两个子

[51nod 1022] 石子归并v2 [dp+四边形不等式优化]

题面: 传送门 思路: 加强版的石子归并,现在朴素的区间dp无法解决问题了 首先我们破环成链,复制一条一样的链并粘贴到原来的链后面,变成一个2n长度的序列,在它上面dp,效率O(8n^3) 显然是过不了的,需要优化 注意:dp的转移如下:dp[i][j]=min(dp[i][k]+dp[k+1][j]+sum(i,j)),其中sum(i,j)表示i到j的价值和,满足区间单调性 因此dp[i][j]也满足区间单调性,可以用四边形不等式优化 我们令s[i][j]等于让dp[i][j]取最小值的那个K

石子归并---区间型动态规划

题目描述 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 样

石子合并 区间dp模板

题意:中文题 Description 在操场上沿一直线排列着 n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的两堆石子合并成新的一堆, 并将新的一堆石子数记为该次合并的得分.允许在第一次合并前对调一次相邻两堆石子的次序. 计算在上述条件下将n堆石子合并成一堆的最小得分. Input 输入数据共有二行,其中,第1行是石子堆数n≤100:第2行是顺序排列的各堆石子数(≤20),每两个数之间用空格分隔. Output 输出合并的最小得分. Sample Input 3 2 5 1 Samp

石子合并(区间dp)

石子合并不应该是个区间dp? 题目:There is an old stone game.At the beginning of the game the player picks n(1<=n<=50000) piles of stones in a line. The goal is to merge the stones in one pile observing the following rules:At each step of the game,the player can me

蓝桥杯:合并石子(区间DP+平行四边形优化)

http://lx.lanqiao.cn/problem.page?gpid=T414 题意:…… 思路:很普通的区间DP,但是因为n<=1000,所以O(n^3)只能拿90分.上网查了下了解了平行四边形优化:地址. 但是看不懂. 1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long LL; 4 const LL INF = 100000000000000000LL; 5 LL dp[1010][101