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)

输出描述 Output Description

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

样例输入 Sample Input

4

4 1 1 4

样例输出 Sample Output

18

数据范围及提示 Data Size & Hint

数据范围相比“石子归并” 扩大了

分类标签 Tags 点此展开

动态规划 区间型DP 单调性DP

枚举长度+四边形不等式优化

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 #include<algorithm>
 6 #define lli long long int
 7 using namespace std;
 8 const int MAXN=5001;
 9 const int maxn=0x7fffffff;
10 void read(int &n)
11 {
12     char c=‘+‘;int x=0;bool flag=0;
13     while(c<‘0‘||c>‘9‘){c=getchar();if(c==‘-‘)flag=1;}
14     while(c>=‘0‘&&c<=‘9‘)
15     x=(x<<1)+(x<<3)+c-48,c=getchar();
16     flag==1?n=-x:n=x;
17 }
18 int n;
19 int a[MAXN];
20 int sum[MAXN];
21 int dp[MAXN][MAXN];
22 int mid[MAXN][MAXN];
23 int  main()
24 {
25     read(n);
26     for(int i=1;i<=n;i++)
27         read(a[i]);
28     for(int i=1;i<=n;i++)
29         sum[i]=a[i]+sum[i-1];
30     for(int i=1;i<=n;i++)
31         dp[i][i]=0,mid[i][i]=i;
32     for(int len=1;len<=n-1;len++)
33     {
34         for(int i=1;i<=n-len;i++)
35         {
36             int j=len+i;
37             dp[i][j]=maxn;
38             for(int k=mid[i][j-1];k<=mid[i+1][j];k++)
39             {
40                 if(dp[i][j]>dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1])
41                 {
42                     dp[i][j]=dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1];
43                     mid[i][j]=k;
44                 }
45             }
46         }
47     }
48
49     printf("%d",dp[1][n]);
50     return 0;
51 }
时间: 2024-08-04 04:12:23

3002 石子归并 3的相关文章

codevs3002 石子归并3

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

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

51nod 1021 石子归并(dp)

51nod 1021 石子归并 题解:从i到j合并的最小值:dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + sum[j] - sum[i-1]); 最后dp[1][n]即为所求结果. 1 #include<cstdio> 2 #include<algorithm> 3 #include<cstring> 4 #define CLR(a,b) memset((a),(b),sizeof((a))) 5 using name

合并类动态规划,石子归并,合并石子解题报告

石子归并问题 1:任意版 有N堆石子,现要将石子有序的合并成一堆,规定如下:每次只能移动任意的2堆石子合并,合并花费为将的一堆石子的数量.设计一个算法,将这N堆石子合并成一堆的总花费最小(或最大). 此类问题比较简单,就是哈夫曼编码的变形,用贪心算法即可求得最优解.即每次选两堆最少的,合并成新的一堆,直到只剩一堆为止.证明过程可以参考哈夫曼的证明过程. 2.链式归并 问题描述 设有N堆沙子排成一排,其编号为1,2,3,-,N(N<=100).每堆沙子有一定的数量.现要将N堆沙子并成为一堆.归并的

codevs 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