基本概念:
通过合并小区间的最优解,得出大区间总区间的最优解,大问题先化成小问题,然后小问题求最优,最后回归(合并)到大问题上去。
算法核心:
就是枚举个长度区间,求每个区间的最优解,然后不断扩张到最大区间的做法。
例题:
282. 石子合并 - AcWing题库https://www.acwing.com/problem/content/284/题目分析:
1.该题目运用到前缀和,求每一个区间才能准确算出这一段区间内的石子个数和。
2.然后核心代码就是枚举每一个区间,求最优解即可。
3.注意区间的范围,和区间边界的取值。
代码如下:
#include <iostream>
#include <algorithm>
#include <cstring>
using namespace std;
const int INF = 0x3f3f3f3f;
int s[1050];
int n;
int f[1050][1050];
int main()
{
cin >> n;
memset(f, INF, sizeof(f));//一定记得初始化赋值,将所有的值赋值成以恶搞很大很大的数
for (int i = 1; i <= n; i++) {
cin >>s[i];
f[i][i] = 0;//自己本身定义为0
}
for (int i = 1; i <= n; i++) {
s[i] += s[i - 1];//求前缀和
}
for (int len = 2; len <= n; len++) {
for (int i = 1; len + i - 1 <= n; i++) {
int l = i; int r = i + len - 1;//枚举区间
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;//最大区间
}
撒花!(区间dp就是依靠枚举每个区间,就思考每个区间的最优解怎么写就行)。