写在前面:
- 开始时间:2021-06-06
博客:
- 我的总结:DP基础知识总结
- 题意贡献:「kuangbin带你飞」专题二十二 区间DP
- 题解贡献:kuangbin专题二十二 区间DP、「kuangbin带你飞」专题二十二 区间DP
- 难度判断:[kuangbin带你飞]专题二十二 区间DP
题目:
1.Cake ZOJ - 3537 :
2.(题解传送门)Halloween Costumes LightOJ - 1422 :区间DP+脱/穿是一个问题
3.(题解传送门)Brackets POJ - 2955 :区间DP+最大括号匹配子序列
4.Coloring Brackets CodeForces - 149D :
5.(无传送门)Multiplication Puzzle POJ - 1651 :
- 题意:给出n(2<=n<=100)个数,每次从中抽出一个数(第一和最后一个不能抽),每次的得分为抽出的数与相邻两个数的乘积,直到只剩下首尾两个数为止,问最小得分是多少?
- 题解:dp[i][j]表示i~j的最小得分,初始化dp[i][i]容易,更新dp[i][j]:枚举i~j中最后一个抽走的数。
- 代码:
#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <string>
// #define int long long
using namespace std;
const int N = 1e2 + 10;
const int INF = 1e9; //最大不超过1e8
int n, dp[N][N];
int a[N];
signed main() {
cin >> n;
int len, i, j, k;
for (i = 1; i <= n; i++) cin >> a[i];
for (i = 2; i <= n - 1; i++)
for (j = i; j <= n - 1; j++) dp[i][j] = INF;
for (i = 2; i <= n - 1; i++) dp[i][i] = a[i - 1] * a[i] * a[i + 1];
for (len = 2; len <= n - 2; len++) {
for (i = 2; i + len - 1 <= n - 1; i++) {
j = i + len - 1;
for (k = i; k <= j; k++) {
dp[i][j] = min(dp[i][j], dp[i][k - 1] + dp[k + 1][j] +
a[i - 1] * a[k] * a[j + 1]);
//注意k-1<i,k+1>j的时候dp应该赋值为0
}
}
}
cout << dp[2][n - 1] << endl;
return 0;
}
/*
inpput:::
6
10 1 50 50 20 5
output:::
3650
*/
- 越来越熟悉区间DP的套路了嘿嘿!!!
6.Food Delivery ZOJ - 3469:题解待理解(让子弹飞一会儿)
7.(题解传送门)You Are the One HDU - 4283 :区间DP+从数组中某种顺序取数
8.(题解传送门)String painter HDU - 2476 :区间DP+字符串a->b的最小操作数&每次能将一个子串改成相同字符的子串
- 区间DP好题!!!
- 分步dp
- 找了很多题解都没理解,去hdu官方oj的discuss才找到能看懂的代码