当前位置: 首页 > news >正文

石子问题(区间dp)

码蹄集OJ-石子合并

#include<bits/stdc++.h> 
using namespace std;
const int N=202;
int n,a[N],sum[N],dp[N][N];
int main( )
{cin>>n;for(int i=1;i<=n;i++){cin>>a[i];a[i+n]=a[i];}for(int i=1;i<=2*n;i++){sum[i]=sum[i-1]+a[i];}for(int i=1;i<=2*n;i++){for(int j=1;j<=2*n;j++){if(i==j){dp[i][j]=0;}else{dp[i][j]=-1e8;}}}for(int len=2;len<=n;len++){for(int i=1;i+len-1<=2*n;i++){int j=i+len-1;for(int k=i;k<j;k++){dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);}}}int result=0;for(int i=1;i<=n;i++){result=max(result,dp[i][i+n-1]);}cout<<result;return 0;
}

将数组的大小扩大一倍(即把原数组复制一份接在后面),将环形问题转换成线性问题解决。

任何环形区间的操作,都能在展开后的双倍线性数组上,通过一个连续的线性区间来表示。

定义dp[i][j]数组表示将i到j之一段石子合并成一堆时的得分。

初始化dp数组,在区间范围为0时,dp数组大小为0。由于题中求的是最小值,其他dp数组定义为无穷小。

枚举区间大小,再枚举起点,这样终点的值可以被确定。定义一个中间值k,遍历从起点到终点的所有值,得出状态转移方程:

 dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]+sum[j]-sum[i-1]);

因为在石子问题中,总值=之前的值+当前的值,当前的值是确定的,通过前面算的累加数组得到起点到终点的值sum[j]-sum[i-1]。之前的值就通过枚举中间值k来表示。

注意:因为题目是环形数组,所以结果不能直接输出dp[1][j]。应该遍历所有起点,得出的最大值才是结果。

http://www.lryc.cn/news/593721.html

相关文章:

  • 泛型机制详解
  • Java中缓存的使用浅讲
  • 从代码学习深度强化学习 - SAC PyTorch版
  • openmv小车追小球
  • PCA主成分分析
  • xss-labs1-8题
  • lvs笔记
  • JAVA高级第六章 输入和输出处理(一)
  • python类Keys
  • OpenCV 官翻 2 - 图像处理
  • CAN通信驱动开发注意事项
  • 使用C#对象将WinRiver项目文件进行复杂的XML序列化和反序列化实例详解
  • 软考高级之工程工期成本计算题
  • 用虚拟机体验纯血鸿蒙所有机型!
  • 深入解析LVS负载均衡核心原理
  • Python MCP与Excel增强智能:构建下一代数据处理和自动化解决方案
  • 线性回归问题
  • 【超详细笔记】概率:中心极限定理的直观理解——样本均值为何趋近正态
  • Linux“一切皆文件“设计哲学 与 Linux文件抽象层:struct file与file_operations的架构解析
  • 使用 validation 框架生成一个校验参数是否在枚举内的校验器
  • 环形区域拉普拉斯方程傅里叶级数解
  • DC-DC降压转换5.5V/3A高效率低静态同步降压转换具有自适应关断功能
  • 基于 Google Earth Engine 的 DEM 鞍部自动提取
  • 动态规划——状压DP经典题目
  • 鸿蒙蓝牙通信
  • 【Java源码阅读系列56】深度解读Java Constructor 类源码
  • GitLab 社区版 10.8.4 安装、汉化与使用教程
  • AI编程工具对比:Cursor、GitHub Copilot与Claude Code
  • 【SVM smote】MAP - Charting Student Math Misunderstandings
  • sqli-labs靶场通关笔记:第32-33关 宽字节注入