当前位置: 首页 > 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.dtcms.com/a/287623.html

相关文章:

  • 【c++】提升用户体验:问答系统的交互优化实践——关于我用AI编写了一个聊天机器人……(12)
  • QCC系列显示交互层的自研技术突破与实践
  • 论文reading学习记录4 - weekly - 视觉端到端开创-LOAM
  • 6 STM32单片机的智能家居安防系统设计(STM32代码+手机APP设计+PCB设计+Proteus仿真)
  • VRRP-虚拟路由冗余协议
  • leetcode3_435 and 605
  • 在服务器(ECS)部署 MySQL 操作流程
  • C++控制台贪吃蛇开发:从0到1绘制游戏世界
  • Linux --进程信号
  • 2025年燃气从业人员证考试题库及答案
  • Linux——文件压缩和解压
  • 结合python面向对象编程,阐述面向对象三大特征
  • volka 可理解性输入:做家务
  • 学习C++、QT---29(QT库中QT事件的介绍和用了几个案例来对事件怎么使用的讲解)
  • lvs原理及实战部署
  • Linux内核设计与实现 - 第5章 系统调用
  • CS231n-2017 Lecture3线性分类器笔记
  • 什么是 Git 的钩子 Hooks?包括哪些内容?
  • picoCTF 2024: [[NoSQL]] Injection - Writeup
  • K8s与Helm实战:从入门到精通
  • 【杂谈】硬件工程师怎么用好AI工具做失效分析
  • 图像缩放的双线性插值算法
  • Keepalived 监听服务切换与运维指南
  • Redis常见线上问题
  • 如何实现电脑自动关机与定时任务管理
  • MySQL 深度性能优化配置实战指南
  • UGUI 性能优化系列:第三篇——渲染与像素填充率优化
  • Redis性能测试全攻略:工具实操与性能优化指南
  • python conda 包管理工具 隔离环境
  • Ubuntu 22.04.3 LTS 安装 MySQL