区间DP——石子合并
状态表示的时候表示的是某一段区间。
动态规划:
1、状态表示:f[i, j] 第i堆到第j堆的区间
1)集合:所有将第i堆和第j堆石子合并成一堆石子的 合并方法的集合
2)min: 所有合并方式代价的最小值
2、状态计算:f[1][n]就是所求的,从第1堆一直合并到第n堆的合并方式的最小值。
最后一定是将两堆合并成一堆,将最后一次合并作为分界线。
PS:所有的减去一个数加上一个数并不会影响最大值和最小值是谁。
[i, k], [k + 1, j]把这最后一步去掉,然后求最小值:f[i, k] + f[k + 1, j] + s[j] - s[i - 1]
然后f[i, j] = Min{f[i, k] + f[k + 1,j] + s[j] - s[i - 1]}, k = i ~ j - 1
时间复杂度:状态两维 O(n^2 * k) = O(n^2 * n) = O(n ^ 3) = 2.7 * 10^7
输入样例:
4
1 3 5 2
输出样例:
22
#include <iostream> #include <algorithm> using namespace std; const int N = 301; int f[N][N], s[N]; int main() { int n; cin>>n; for(int i = 1;i <= n;i++) cin>>s[i]; for(int i = 1;i <= n;i++) s[i] += s[i-1]; for(int len = 2;len <= n;len++) for(int i = 1; i + len - 1 <= n;i++) { int l = i, r = i + len - 1; f[l][r] = 1e9; for(int k = l; k < r; k++) f[l][r] = min(f[l][r], f[l][k] + f[k+1][r] + s[r] - s[l - 1]); } cout<<f[1][n]<<endl; }
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?