区间DP 入门
Posted 不知姓名的黑猫君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了区间DP 入门相关的知识,希望对你有一定的参考价值。
首先我们先需要知道区间是如何用dp来做的,让我们来看一下模板。
1 for (int i = 1; i <= n; i++){//枚举区间里面的个数 2 for (int j = 1; j <= 能枚举到得最大的pos; j++){ 3 int p = i + j - 1;//表示在目前能到达的最大值的坐标 4 if (p > n) break; 5 for (int k = j; k <= p; k++){ 6 dp[j][p] = min or max(dp[j][p], dp[j][k] + dp[k + ][p] + j to p 的 val); 7 } 8 } 9 }
①石子问题
http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=737
这个就是很显然的模板题目了。
可以提前用sum[]来维护区间的和,或者也可以用树状数组维护。
#include<cstdio> #include<algorithm> #include<cstring> using namespace std; const int maxn = 200 + 5; const int inf = 0x3f3f3f3f; int dp[maxn][maxn]; int a[maxn]; int sum[maxn]; int n; int main(){ while (scanf("%d", &n) == 1){ for (int i = 1; i <= n; i++) scanf("%d", a + i); memset(dp, 0, sizeof(dp)); memset(sum, 0, sizeof(sum)); for (int i = 1; i <= n; i++){ sum[i] = sum[i - 1] + a[i]; } for (int i = 2; i <= n; i++){ for (int j = 1; j <= n - i + 1; j++){ int p = j + i - 1; if (p > n) break; dp[j][p] = inf; for (int k = j; k <= p; k++){ dp[j][p] = min(dp[j][p], dp[j][k] + dp[k + 1][p] + sum[p] - sum[j - 1]); } } } printf("%d\\n", dp[1][n]); } return 0; }
②
以上是关于区间DP 入门的主要内容,如果未能解决你的问题,请参考以下文章