【四边形不等式】COGS1658- [HZOI 2014] 合并石子

【题目大意】

在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。试设计出1个算法,计算出将N堆石子合并成1堆的最小得分和最大得。

【思路】

设 dp[i][j] 表示第 i 到第 j 堆石子合并的最优值,sum[i][j] 表示第 i 到第 j 堆石子的总数量。

 1 #include<iostream>
 2 #include<cstdio>
 3 using namespace std;
 4 const int N=205;
 5 const int INF=0x7fffffff;
 6 int n;
 7 int a[N],sum[N],dp[N][N],s[N][N];
 8
 9 void f()
10 {13      for (int i=1;i<=n;i++) dp[i][i]=0,s[i][i]=i;
14      for (int r=1;r<n;r++)
15      {
16          for (int i=1;i<n;i++)
17         {
18             int j=i+r;
19             if(j>n) break;
20             dp[i][j]=INF;
21             for (int k=s[i][j-1];k<=s[i+1][j];k++)
22             {
23                 if(dp[i][j]>dp[i][k]+dp[k+1][j])
24                 {
25                     dp[i][j]=dp[i][k]+dp[k+1][j];
26                     s[i][j]=k;
27                 }
28             }
29             dp[i][j]+=sum[j]-sum[i-1];
30         }
31     }
32 }
33
34 int main()
35 {
36      while(~scanf("%d",&n))
37      {
38          sum[0]=0;
39         for (int i=1;i<=n;i++)
40         {
41             scanf("%d",&a[i]);
42             sum[i]=sum[i-1]+a[i];
43         }
44         f();
45         printf("%d\n",dp[1][n]);
46      }
47      return 0;
48
49 }
时间: 2024-10-14 17:48:54

【四边形不等式】COGS1658- [HZOI 2014] 合并石子的相关文章

四边形不等式优化DP——石子合并问题 学习笔记

好方啊马上就要区域赛了连DP都不会QAQ 毛子青<动态规划算法的优化技巧>论文里面提到了一类问题:石子合并. n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分. 求出将n堆石子合并成一堆的最小得分和最大得分以及相应的合并方案. 设m[i,j]表示合并d[i..j]所得到的最小得分. 状态转移方程: 总的时间复杂度为O(n3). [优化方案] 四边形不等式: m[i,j]满足四边形不等式 令s[i,j]=max{k | m[

石子合并(四边形不等式优化dp)

该来的总是要来的———————— 经典问题,石子合并. 对于 f[i][j]= min{f[i][k]+f[k+1][j]+w[i][j]} From 黑书 凸四边形不等式:w[a][c]+w[b][d]<=w[b][c]+w[a][d](a<b<c<d) 区间包含关系单调: w[b][c]<=w[a][d](a<b<c<d) 定理1:  如果w同时满足四边形不等式和决策单调性 ,则f也满足四边形不等式 定理2:  若f满足四边形不等式,则决策s满足 s[i

石子合并(四边形不等式优化)

题目大意很简单,和普通的石子合并过程没有区别,只是花费变成了一个多项式,若连续的任意个石子权值和为x,那么代价变为F(x) = sigma(a[i] * x^i),求将n堆石子合并为一队的最小花费. 对于暴力的做法,复杂度是O(n^3)的,所以要优化 我们知道当a, b, c, d(a <= b < c <= d)当有cost[a][c] + cost[b][d] <= cost[a][d] + cost[b][c] 时,我们称其满足四边形不等式,设p[i][j]表示当区间[i,

四边形不等式优化石子合并Codevs3002题解

题目描述 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 样例输出 S

四边形不等式优化_石子合并问题_C++

在动态规划中,经常遇到形如下式的状态转移方程: m(i,j)=min{m(i,k-1),m(k,j)}+w(i,j)(i≤k≤j)(min也可以改为max) 上述的m(i,j)表示区间[i,j]上的某个最优值.w(i,j)表示在转移时需要额外付出的代价.该方程的时间复杂度为O(N3) 下面我们通过四边形不等式来优化上述方程,首先介绍什么是“区间包含的单调性”和“四边形不等式” 1.区间包含的单调性:如果对于 i≤i'<j≤j',有 w(i',j)≤w(i,j'),那么说明w具有区间包含的单调性.

合并石子 四边形不等式优化

题目描述 有一排石子,共n 堆.现要将石子有次序地合并成一堆.规定每次只能选相邻的2 堆石子合并成新的一堆,并将新的一堆石子数记为该次合并的得分.试设计一个算法,计算出将n堆石子合并成一堆的最小得分. 题解 首先由直接动态规划的方法来做,即 for(int i=1;i<=n;i++) for(int j=i;j<=n;j++) for(int k=i;k<=j;k++) { f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+cost[j]-cost[i-1]);

石子合并问题(四边形不等式DP优化)

有很多种算法: 1,任意两堆可以合并:贪心+单调队列. 2,相邻两堆可合并:区间DP(  O(n^3)) ). 3,相邻,四边形不等式优化DP(O(n^2) ). 4,相邻,GarsiaWachs算法(O(n^2)). 这里实现了第三种解法:

四边形不等式(石子合并)

动态规区间dp做这道题的话应该是n^3,下面的代码优化到了n^2,用四边形不等式优化. 设mid[i][j]是dp[i][j]的最优解的断点,即它左区间的右端点,那么mid[i][j-1]<=mid[i][j]<=mid[i+1][j],所以在求解dp[i][j]时,枚举k可以只枚举这两个值之间枚举就好, 程序要先枚举区间长度,在枚举左端点,枚举每个区间长度时,他们的k总是只从1到n,只走一遍,所以这就相当于优化了一层,变成了O(n2)的. 比如len长度为3时,dp[1][3]只会枚举mid

51nod 1022 石子归并 V2(四边形不等式)

分析:记dp[i][j]为从i到j合并的最小代价(顺时针,i可以大于j),sum[i][j]为从i到j的和,则dp[i][j]=min{dp[i][k-1]+dp[k][j]}+sum[i][j],(i<k<=j),直接求的话复杂度为O(n^3),会T. 四边形不等式优化:记s[i][j]为dp[i][j]取得最小值时对应的k值,则有dp[i][j]=min{dp[i][k-1]+dp[k][j]}+sum[i][j],(s[i][j-1]<=k<=s[i+1][j]),可以证明,