【记录】OJ|区间DP|石子合并(环形)
1. 题干
描述
在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分。
试设计出一个算法,计算出将N堆石子合并成1堆最大得分.
输入
第1行一个正整数N,1≤N≤2000,表示有N堆石子.
第2行有N个数,分别表示每堆石子的个数.
输出
共1行,最大得分
输入样例1
4
4 4 5 9
输出样例1
54
2. 解
1) 原理概述
以最大值为例。
本问题采用了分冶的思想,是先求解小区间中的解,再合并到大区间中。
Fmax[i][j]
意为区间[i,j]
内合并的最大得分,t[i][j]
意为区间[i,j]
中的石子总分。
① 状态转移方程:
② 经过平行四边形优化后的状态转移方程:
平行四边形优化的结论:使两堆的合并值最大的分割点,一定将堆[i,j]分成[i+1,j],[i,i]或者[i,j-1],[j,j]这两堆。
证明:(下图来自 HUST 课堂,笔者根据自己的理解将证明完善并添加了颜色和符号标记)
③ 环状结构优化(下图来自 HUST 课堂):
2) 代码实现(以循环结构为例):
#include<stdio.h>
#pragma warning(disable:4996)
#define TYPE_ull unsigned long long
//DP问题
TYPE_ull t[4005] = { 0 };
TYPE_ull F[4005][4005] = { 0 }, Max = 0;
TYPE_ull max(TYPE_ull i, TYPE_ull j)
{
if (i > j)
return i;
else return j;
}
TYPE_ull f(int n)
{
Max = 0;
//F[i][j]意为区间(i,j)内合并的最大得分
//for (int i = 1; i <= n; ++i)
//{
// F[i][i + 1] = t[i + 1] - t[i - 1];//取相邻两数合并得分为两数之和
//}
//for (int i = 1; i <= n; ++i)
//{
// F[i][i + 2] = max(F[i][i + 1], F[i + 1][i + 2]) + t[i + 2] - t[i - 1];//取间隔为2的F区间
//}
//...
for (int v = 1; v < n; ++v)//间隔为v,从间隔为1算起,将递归转换为循环,算间隔为n-1为止即可
{
for (int i = 1; i <= 2 * n; ++i)
{
if (i + v < 2 * n)//注意不能越界
F[i][i + v] = max(F[i][i + v - 1], F[i + 1][i + v]) + t[i + v] - t[i - 1];//取间隔为v的F区间
}
}
for (int i = 1; i <= n; ++i)
{
Max = max(F[i][n + i - 1], Max);
}
return Max;
}
int main()
{
int n, k;
scanf("%d", &n);
for (int i = 1; i <= n; ++i)
{
scanf("%d", &k);
t[i] = t[i - 1] + k;
}
for (int i = 1; i <= n; ++i)
{
t[n + i] = t[n] + t[i];
}
printf("%llu\n", f(n));
return 0;
}
3) 笔者被坑到的地方
- 迭代转循环:分冶思想,若直接计算
F[1][n]
这个最大问题,那么小问题还没算出来,最终的结果肯定是错的。为了计算小问题,可以将所有的小问题从最小的开始求。设定间隔为1,先写一个求解所有间隔为1的循环:
for (int i = 1; i <= n; ++i)
{
F[i][i + 1] = t[i + 1] - t[i - 1];//取相邻两数合并得分为两数之和
}
然后再写间隔为2的:
for (int i = 1; i <= n; ++i)
{
F[i][i + 2] = max(F[i][i + 1], F[i + 1][i + 2]) + t[i + 2] - t[i - 1];//取间隔为2的F区间
}
最后把间隔处理成一个新的循环即可。
- 边界处理:要算间隔为1到(n-1)的所有区间,但是注意,当区间的初值为i的时候,它的末值最大仍然只能取n,区间长度最多为(n-i)。
【记录】OJ|区间DP|石子合并(环形)的更多相关文章
- 区间DP石子合并问题 & 四边形不等式优化
入门区间DP,第一个问题就是线性的规模小的石子合并问题 dp数组的含义是第i堆到第j堆进行合并的最优值 就是说dp[i][j]可以由dp[i][k]和dp[k+1][j]转移过来 状态转移方程 dp[ ...
- 洛谷P1880 石子合并(区间DP)(环形DP)
To 洛谷.1880 石子合并 题目描述 在一个园形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1 ...
- P1880 [NOI1995]石子合并[环形DP]
题目来源:洛谷 题目描述 在一个圆形操场的四周摆放N堆石子,现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆合并成新的一堆,并将新的一堆的石子数,记为该次合并的得分. 试设计出1个算法,计算出将 ...
- Luogu【P1880】石子合并(环形DP)
先放上luogu的石子合并题目链接 这是一道环形DP题,思想和能量项链很像,在预处理过程中的手法跟乘积最大相像. 用一个m[][]数组来存储石子数量,m[i][j]表示从第 i 堆石子到第 j 堆石子 ...
- DP石子合并问题
转自:http://www.hnyzsz.net/Article/ShowArticle.asp?ArticleID=735 [石子合并] 在一个圆形操场的四周摆放着n 堆石子.现要将石子有次序 ...
- 四边形不等式优化DP——石子合并问题 学习笔记
好方啊马上就要区域赛了连DP都不会QAQ 毛子青<动态规划算法的优化技巧>论文里面提到了一类问题:石子合并. n堆石子.现要将石子有次序地合并成一堆.规定每次只能选相邻的2堆石子合并成新的 ...
- 区间DP中的环形DP
vijos1312 链接:www.vijos.org/p/1312 题目分析:经典的环形DP(区间DP) 环形DP,首先解环过程,把数组复制一遍,n个数变成2n个数,从而实现解环 dp[i][j]表示 ...
- 洛谷P1063 能量项链(区间DP)(环形DP)
To 洛谷.1063 能量项链 题目描述 在Mars星球上,每个Mars人都随身佩带着一串能量项链.在项链上有N颗能量珠.能量珠是一颗有头标记与尾标记的珠子,这些标记对应着某个正整数.并且,对于相邻的 ...
- 石子合并(直线版+环形版)&(朴素写法+四边形优化+GarsiaWachs算法)
石子合并-直线版 (点击此处查看题目) 朴素写法 最简单常见的写法就是通过枚举分割点,求出每个区间合并的最小花费,从而得到整个区间的最小花费,时间复杂度为O(n^3),核心代码如下: ; i < ...
- 「区间DP」「洛谷PP3146 」[USACO16OPEN]248 G
[USACO16OPEN]248 G 题目: 题目描述 Bessie likes downloading games to play on her cell phone, even though sh ...
随机推荐
- Typecho复制文章自带版权说明
自带版权说明代码 <script> document.body.addEventListener('copy', function (e) { if (window.getSelectio ...
- Hadoop - HDFS 概述
什么是HDFS HDFS的优缺点 HDFS的文件块大小 HDFS的写数据流程 HDFS的副本配置策略 HDFS读数据的流程 什么是HDFS HDFS(Hadoop Distributed File S ...
- 分享4款.NET开源、免费、实用的商城系统
前言 今天大姚给大家分享4款.NET开源.免费.实用的商城系统,希望可以帮助到有商城系统开发需求的同学. nopCommerce nopCommerce是一个.NET开源功能丰富.免费.灵活且可定制的 ...
- Linux云服务器如何安装配置Redis
为大家分享linux云服务器如何安装配置Redis,示例为CentOS7系统 Redis 是一款开源的高性能内存数据库,以极速读写(微秒级)和丰富数据结构著称,支持字符串.哈希.列表等类型,兼具持久化 ...
- 【Python】将网格数据写入到VTK文件
1. vtk 文件格式 根据官网进行总结 vtk文件组成:5个部分. 第一部分,第一行:表明文件版本.写"# vtk DataFile Version 2.0"就行 第二部分,第二 ...
- 【MATLAB习题】工程测试时域、频域分析
代码: classdef App_uoye < matlab.apps.AppBase % Properties that correspond to app components proper ...
- wordpress设置自定义字体
wordpress设置自定义字体: 失败的操作过程: 写在最前:试了一天多的引用字体,方法包括但不限于: 下载.ttf..otf格式字体,转化为wotf .wotf2格式,挂在github仓库用CDN ...
- next.js 添加 PWA 渐进式WEB应用(service-worker) 支持
本文仅作为 next 系列文章中的一部分,其他 next 文章参考: https://blog.jijian.link/categories/nextjs/ 去 github 搜索了一把,估计是我关键 ...
- 解决 Docker 日志文件太大的问题
Docker 在不重建容器的情况下,日志文件默认会一直追加,时间一长会逐渐占满服务器的硬盘的空间,内存消耗也会一直增加,本篇来了解一些控制日志文件的方法. 清理单个文件 运行时控制 全局配置 Dock ...
- 视觉SLAM第四讲李群与李代数习题
视觉SLAM第四讲李群与李代数习题 一.验证\(SO(3).SE(3).SIM(3)\)关于乘法成群 首先引入一下群的定义. 群 (Group) 是一种集合加上一种运算的代数结构.我们把集合记作 \( ...