博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
环形石子合并问题 - 经典DP问题
阅读量:6307 次
发布时间:2019-06-22

本文共 1920 字,大约阅读时间需要 6 分钟。

hot3.png

 

 ============================================================

 

又是一道超经典的题目。
对于线性的合并石子问题,dp模型类似于“加括号”那类型的dp题目,设 f(i, j)为 将第i项到第j项合并得到的最优解
关键是,这题目是环形的。环形结构,经常采用双倍长度线性化手段,也就是说,把环形结构看成是长度为环的两倍的线性结构来处理。
环的长度是N,所以题目相当于有一排石子1....N+N,然后就可以用线性的石子合并问题的方法做了。
有个要注意的地方,f(i, j) 总是与 f(N +i, N +j) 相等的,所以可以减少一些不必要的计算。

 

#include 
#include
using namespace std;int _sum[205];int a[205];int N;int f[205][205];int g[205][205];int getSegmentSum(int i, int j) { return _sum[j] - _sum[i] + a[i];}int dp(int i, int j) { int & ans = f[i][j]; if (ans != -1) return ans; if (i == j) return ans = 0; if (i + 1 == j) return ans = getSegmentSum(i , j); if (i <= N && j <= N) return ans = dp(N + i, N + j); ans = 2000000000; int s = getSegmentSum(i, j); for (int k = i; k < j; ++k) { ans = min(ans, dp(i, k) + dp(k + 1, j) + s); } return ans;}int dp2(int i, int j) { int & ans = g[i][j]; if (ans != -1) return ans; if (i == j) return ans = 0; if (i + 1 == j) return ans = getSegmentSum(i , j); if (i <= N && j <= N) return ans = dp2(N + i, N + j); ans = -2000000000; int s = getSegmentSum(i, j); for (int k = i; k < j; ++k) { ans = max(ans, dp2(i, k) + dp2(k + 1, j) + s); } return ans;}void input() { int i, j; scanf("%d", &N); for (i = 1; i <= N; ++i) { scanf("%d", &(a[i])); } for (i = N + 1; i <= N + N; ++i) a[i] = a[i - N]; _sum[1] = a[1]; for (i = 2; i <= N + N; ++i) _sum[i] = a[i] + _sum[i - 1]; for (i = 0; i < 205; ++i) for (j = 0; j < 205; ++j) f[i][j] = g[i][j] = -1;}int main() { input(); int i, j; for (i = N + N; i >= 1; --i) for (j = i; j <= N + N; ++j) { dp(i, j); dp2(i, j); } int ans = 2000000000; for (i = 1; i <= N; ++i) { ans = min(ans, dp(i, i + N - 1)); } int ans2 = -2000000000; for (i = 1; i <= N; ++i) { ans2 = max(ans2, dp2(i, i + N - 1)); } printf("%d\n%d\n", ans, ans2); return 0;}

转载于:https://my.oschina.net/mustang/blog/58177

你可能感兴趣的文章
HTML5-placeholder属性
查看>>
Android选择本地图片过大程序停止的经历
查看>>
poj 2187:Beauty Contest(旋转卡壳)
查看>>
《Flask Web开发》里的坑
查看>>
Python-库安装
查看>>
Git笔记
查看>>
普通人如何从平庸到优秀,在到卓越
查看>>
SLAM数据集
查看>>
c#学习笔记05——数组&集合
查看>>
【图论算法】Dijstra&BFS
查看>>
注册和上传文件(头像)
查看>>
使用OVS
查看>>
键盘回收的几种方法
查看>>
Python(条件判断和循环)
查看>>
day4 linux安装python
查看>>
LeetCode Container With Most Water (Two Pointers)
查看>>
vue (v-if show 问题)
查看>>
https基础
查看>>
css3 canvas之刮刮卡效果
查看>>
并查集模板
查看>>