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

石子合并(一排的和一个环的)

石子合并

石子合并是环形dp的经典题,要做它我们首先要做它的弱化版,也就是排成一排的情况:石子合并(弱化版)(洛谷p1775)

石子合并弱化版解法

对于这道题,可以先从简单的情况开始考虑;比如现在要合并a,b,c三堆石子,那么显然只有先合并a,b两队石子和先合并b,c两队石子两种情况,也就是说:

\[f[1][3]=min(f[1][2]+f[3][3],f[1][1]+f[2][3])+v[1][3]; \]

\[//f[i][j]表示合并第i到第j堆石子所要花费的代价,v[i][j]表示第i到j堆石子的总质量 \]

同样的,对于4堆石子a,b,c,d,可以先合并b,c,d,也可以先合并a,b,也可以先合并a,b,c,即可以从a,b,c,d之间的三个空隔中的任意一个隔开,将石子分成两堆,然后分别合并两堆,最后找代价的最小值;

于是就可以得到这样的一个dp思路:枚举一个L表示合并的区间长度从1到n(n是石子堆数),然后在每一个区间内再枚举断点k,求出每个区间所用代价的最小值,最后的答案落在区间[1,n];这种通过短区间转移到大区间的dp思路就是区间dp;

代码如下:

#include<bits/stdc++.h>
using namespace std;
int n,m[305],f[305][305],v[305][305];//f和V的含义同上
int main(){cin>>n;for(int i=1;i<=n;i++){cin>>m[i];}for(int i=1;i<=n;i++){for(int j=i;j<=n;j++){v[i][j]=v[i][j-1]+m[j];//处理出所有区间的石子重量和}}for(int l=1;l<n;l++){//枚举区间长度for(int i=1;i<=n-l;i++){int j=i+l;f[i][j]=0x3f3f3f3f;for(int k=i;k<j;k++){//枚举断点f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+v[i][j]);//转移方程}}}cout<<f[1][n];//答案落在区间[1,n]return 0;
}

石子合并

p1880
接下来就可以怎么把刚才的做法变成环形的,显然最容易想到的做法就是破环为链,这样就可以套用刚才的做法了;但是如果这样做就需要枚举在原序列的每一个点上破环得到的结果,时间复杂度无法接受;

其实可以想到这样一种思路:同样是破环为链,但是我可以保证只在破环之后的这个新序列上做一次区间dp可以覆盖到所有情况;有没有这样的处理方法呢?显然是有的:把原序列复制一遍接到它后面就可以了;比如对于序列4 7 3 5,处理之后的新序列就是4 7 3 5 4 7 3 5;可以发现新序列上每一个长度为4的区间就是破环为链的一种结果;

代码如下:

#include<bits/stdc++.h>
using namspace std;
int n,m[210],f[210][210],v[210][210],f2[210][210];//f是最小值,f2是最大值
int main(){int ans1=0x3f3f3f3f,ans2=-0x3f3f3f3f;cin>>n;for(int i=1;i<=n;i++){cin>>m[i];}for(int i=n+1;i<=n+n;i++){//复制一遍原序列m[i]=m[i-n];}for(int i=1;i<=n+n;i++){for(int j=i;j<=n+n;j++){v[i][j]=v[i][j-1]+m[j];}}for(int l=1;l<n;l++){//枚举的区间长度仍然是原序列的长度for(int i=1;i<=n+n-l;i++){int j=i+l;f[i][j]=0x3f3f3f3f;f2[i][j]=-0x3f3f3f3f;for(int k=i;k<j;k++){f[i][j]=min(f[i][j],f[i][k]+f[k+1][j]+v[i][j]);f2[i][j]=max(f2[i][j],f2[i][k]+f2[k+1][j]+v[i][j]);//相同的转移方法}}}for(int i=1;i<=n;i++){//求出所有情况的最值ans1=min(ans1,f[i][i+n-1]);ans2=max(ans2,f2[i][i+n-1]);}cout<<ans1<<endl<<ans2;return 0;
}
http://www.hskmm.com/?act=detail&tid=18911

相关文章:

  • 思维题练习
  • NXP - 用MCUXpresso IDE导入lpcopen_2_10_lpcxpresso_nxp_lpcxpresso_1769.zip中的工程 - 教程
  • spatial项目的主要领导者斯坦福大学ppl实验室的 Kunle Olukotun 教授和 Christos Kozyrakis 教授
  • 程序语言杂谈:概述
  • 字符串基础
  • 在CodeBolcks下wxSmith的C++编程教程——使用 wxGrid
  • 题解:P12479 [集训队互测 2024] 长野原龙势流星群
  • linux下nginx
  • 9.27
  • OI 笑传 #12
  • spatial芯片设计语言 学习笔记
  • 【C++】23. C++11(上) - 教程
  • kali2025搭建ARL灯塔系统
  • 实用指南:AI 术语通俗词典:LLM(大语言模型)
  • java学习 2025-9-27
  • 题解:P11667 [USACO25JAN] Astral Superposition B
  • 北极通讯网络题解(做题记录)
  • elasticsearch安装插件 - 实践
  • 个人学习——前端react项目框架
  • 软件基础第一次作业
  • LGP9755 [CSP-S 2023] 种树 学习笔记
  • 7、revision 是 Maven 3.5+ 引入的现代版本管理机制 - 实践
  • P1731 生日蛋糕 做题记录
  • 如何有效提升代码覆盖率:从单元测试到集成测试的实践指南
  • Spring知识点(2)
  • 超越实习期的AI自动化工具:播客工作流与Slack导出器实战
  • 调度器的各项指标以及计算方式
  • 浅谈dsu on tree
  • JavaDay10
  • 昇腾多机推理极速上手:10倍简化的 DeepSeek R1 超大规模模型部署