区间dp入门[POJ2955][HDU2476][POJ3186][POJ1651][HDU4632][HDU4283][HDU4570][POJ3280]
2015-08-15 17:32
597 查看
区间dp问题,通常给出一个序列,用dp[ i ][ j ] 表示序列为ai,a(i + 1)...aj时的答案,而较长的序列的答案由较短的序列的答案递推得到,让人想到矩阵连乘顺序问题。
所以解题的时候会用到3个循环:
第一层枚举序列长度 jj
第二层枚举序列开头的位置 i
第三层枚举序列 [i, i + jj ] 中间点 k,其中第三层有时是不需要的
下面是一些区间dp入门题,大同小异,这里就不给出思路了,看下代码大概就明白了
题目:POJ 2955 http://poj.org/problem?id=2955
代码:
题目:HDU 2476 http://acm.hdu.edu.cn/showproblem.php?pid=2476
代码:
题目:POJ 3186 http://poj.org/problem?id=3186
代码:
题目:POJ 1651 http://poj.org/problem?id=1651
代码:
题目:HDU 4632 http://acm.hdu.edu.cn/showproblem.php?pid=4632
代码:
题目:HDU 4283 http://acm.hdu.edu.cn/showproblem.php?pid=4283
代码:
题目:HDU 4570 http://acm.hdu.edu.cn/showproblem.php?pid=4570
代码:
题目:POJ 3280 http://poj.org/problem?id=3280
代码:
所以解题的时候会用到3个循环:
第一层枚举序列长度 jj
第二层枚举序列开头的位置 i
第三层枚举序列 [i, i + jj ] 中间点 k,其中第三层有时是不需要的
下面是一些区间dp入门题,大同小异,这里就不给出思路了,看下代码大概就明白了
题目:POJ 2955 http://poj.org/problem?id=2955
代码:
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #define MOD 1000000007 #define INF 0x7fffffff using namespace std; int dp[105][105]; char s[105]; int match(int l, int r) { if(s[l] == '(' && s[r] == ')') return 1; if(s[l] == '[' && s[r] == ']') return 1; return 0; } int main() { #ifdef LOCAL freopen("dpdata.txt", "r", stdin); #endif while(scanf("%s", s) != EOF && s[0] != 'e') { int len = strlen(s); memset(dp, 0, sizeof(dp)); for(int jj = 1; jj < len; jj++) { for(int i = 0; i + jj < len; i++) { int j = i + jj; if(match(i, j)) { dp[i][j] = max(dp[i][j], dp[i + 1][j - 1] + 2); } for(int k = i; k < j; k++) { dp[i][j] = max(dp[i][j], dp[i][k] + dp[k + 1][j]); } //printf("dp[%d][%d]=%d\n", i, j, dp[i][j]); } } printf("%d\n", dp[0][len - 1]); } return 0; }
题目:HDU 2476 http://acm.hdu.edu.cn/showproblem.php?pid=2476
代码:
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #define MOD 1000000007 #define INF 0x7fffffff using namespace std; char A[105], B[105]; int dp[105][105], ans[105]; int main() { #ifdef LOCAL freopen("dpdata.txt", "r", stdin); #endif int l, r; while(scanf("%s%s", A, B) != EOF) { int len = strlen(A); memset(dp, 0, sizeof(dp)); for(int jj = 0; jj < len; jj++) { for(int i = 0; i + jj < len; i++) { int j = i + jj; dp[i][j] = dp[i + 1][j] + 1; for(int k = i + 1; k <= j; k++) { if(B[i] == B[k]) dp[i][j] = min(dp[i][j], dp[i + 1][k] + dp[k + 1][j]); } //printf("dp[%d][%d]=%d\n", i, j, dp[i][j]); } } for(int i = 0; i < len; i++) ans[i] = dp[0][i]; for(int i = 0; i < len; i++) { if(B[i] == A[i]) { if(i == 0) ans[i] = 0; else ans[i] = ans[i - 1]; } else { for(int j = 0; j < i; j++) { ans[i] = min(ans[i], ans[j] + dp[j + 1][i]); } } } printf("%d\n", ans[len - 1]); } return 0; }
题目:POJ 3186 http://poj.org/problem?id=3186
代码:
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #define MOD 1000000007 #define INF 0x7fffffff using namespace std; int v[2005], sum[2005], dp[2005][2005], a[2005][2005]; int main() { #ifdef LOCAL freopen("dpdata.txt", "r", stdin); #endif int n; while(scanf("%d", &n) != EOF) { memset(dp, 0, sizeof(dp)); memset(a, 0, sizeof(a)); for(int i = 0; i < n; i++) { scanf("%d", &v[i]); dp[i][i] = v[i]; a[i][i] = v[i]; //printf("a[%d][%d]=%d\n", i, i, a[i][i]); } sum[0] = v[0]; for(int i = 1; i < n; i++) { sum[i] = sum[i - 1] + v[i]; a[0][i] = sum[i]; //printf("a[0][%d]=%d\n", i, a[0][i]); } for(int i = 1; i < n; i++) { for(int j = i + 1; j < n; j++) { a[i][j] = sum[j] - sum[i - 1]; //printf("a[%d][%d]=%d\n", i, j, a[i][j]); } } for(int jj = 1; jj < n; jj++) { for(int i = 0; i + jj < n; i++) { int j = i + jj; dp[i][j] = max(dp[i][j], dp[i + 1][j] + a[i + 1][j] + a[i][i]); dp[i][j] = max(dp[i][j], dp[i][j - 1] + a[i][j - 1] + a[j][j]); //printf("dp[%d][%d]=%d\n", i, j, dp[i][j]); } } printf("%d\n", dp[0][n -1]); } return 0; }
题目:POJ 1651 http://poj.org/problem?id=1651
代码:
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #define MOD 1000000007 #define INF 0x7fffffff using namespace std; int dp[105][105]; int main() { #ifdef LOCAL freopen("dpdata.txt", "r", stdin); #endif int n, a[105]; while(scanf("%d", &n) != EOF) { for(int i = 0; i < n; i++) { scanf("%d", &a[i]); } for(int i = 0; i <= n; i++) { for(int j = 0; j <= n; j++) dp[i][j] = 100000100; } for(int i = 1; i < n - 1; i++) { dp[i - 1][i + 1] = a[i - 1] * a[i] * a[i + 1]; //printf("dp[%d][%d]=%d\n", i - 1, i + 1, dp[i - 1][i + 1]); } for(int jj = 3; jj < n; jj++) { for(int i = 0; i + jj < n; i++) { int j = i + jj; for(int k = i + 2; k + 1< j; k++) { dp[i][j] = min(dp[i][j], dp[i][k] + dp[k][j] + a[i] * a[k] * a[j]); } dp[i][j] = min(dp[i][j], dp[i][j - 1] + a[i] * a[j - 1] * a[j]); dp[i][j] = min(dp[i][j], dp[i + 1][j] + a[i] * a[i + 1] * a[j]); //printf("dp[%d][%d]=%d\n", i, j, dp[i][j]); } } printf("%d\n", dp[0][n - 1]); } return 0; }
题目:HDU 4632 http://acm.hdu.edu.cn/showproblem.php?pid=4632
代码:
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #define MOD 10007 #define INF 0x7fffffff using namespace std; char s[1005]; int dp[1005][1005]; int main() { #ifdef LOCAL freopen("dpdata.txt", "r", stdin); #endif int t; scanf("%d", &t); for(int cas = 1; cas <= t; cas++) { scanf("%s", s); int len = strlen(s); memset(dp, 0, sizeof(dp)); for(int i = 0; i < len; i++) { dp[i][i] = 1; } for(int jj = 1; jj < len; jj++) { for(int i = 0; i + jj < len; i++) { int j = i + jj; dp[i][j] = max(dp[i][j], dp[i][j - 1] + dp[i + 1][j] - dp[i + 1][j - 1] + MOD); if(s[i] == s[j]) { dp[i][j] += dp[i + 1][j - 1] + 1 + MOD; } dp[i][j] %= MOD; } } printf("Case %d: %d\n", cas, dp[0][len - 1]); } return 0; }
题目:HDU 4283 http://acm.hdu.edu.cn/showproblem.php?pid=4283
代码:
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #define MOD 1000000007 #define INF 0x7fffffff using namespace std; int d[105], dp[105][105], a[105][105], sum[105]; int main() { #ifdef LOCAL freopen("dpdata.txt", "r", stdin); #endif int t, n; scanf("%d", &t); for(int cas = 1; cas <= t; cas++) { scanf(" %d", &n); memset(dp, 0, sizeof(dp)); memset(a, 0, sizeof(a)); for(int i = 0; i < n; i++) { scanf("%d", &d[i]); dp[i][i] = 0; a[i][i] = d[i]; } sum[0] = d[0]; for(int i = 1; i < n; i++) { sum[i] = a[0][i] = sum[i - 1] + d[i]; } for(int i = 0; i < n; i++) { for(int j = i + 1; j < n; j++) { dp[i][j] = 1000010; if(i > 0)a[i][j] = sum[j] - sum[i - 1]; //printf("a[%d][%d]=%d\n", i, j, a[i][j]); } } for(int j = 1; j < n; j++) { for(int i = 0; i + j < n; i++) { //dp[i][i + j] = min(dp[i][i + j], dp[i + 1][i + j] + a[i + 1][i + j]); for(int k = 0; k <= j; k++) { dp[i][i + j] = min(dp[i][i + j], dp[i + 1][i + k] + k * a[i][i] + dp[i + k + 1][i + j] + (k + 1) * a[i + k + 1][i + j]); } //dp[i][i + j] = min(dp[i][i + j], dp[i + 1][i + j] + a[i][i] * j); //printf("dp[%d][%d]=%d\n", i, i + j, dp[i][i + j]); } } printf("Case #%d: %d\n", cas, dp[0][n - 1]); } return 0; }
题目:HDU 4570 http://acm.hdu.edu.cn/showproblem.php?pid=4570
代码:
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #define MOD 1000000007 #define INF 1 << 30 - 1 typedef long long ll; using namespace std; ll dp[70][70], a[70]; int main() { #ifdef LOCAL freopen("dpdata.txt", "r", stdin); #endif int t, n; //printf("INF=%I64d\n", INF); scanf("%d", &t); while(t--) { scanf("%d", &n); memset(dp, 0, sizeof(dp)); for(int i = 0; i < n; i++) { scanf("%I64d", &a[i]); } for(int i = 0; i < n; i++) { dp[i][i] = a[i] * 2; for(int j = i + 1; j < n; j++) { dp[i][j] = INF; } } for(int jj = 1; jj < n; jj++) { for(int i = 0; i + jj < n; i++) { int j = i + jj; for(int k = i; k < j; k++) { dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j]); if(jj <= 19) { ll cur = a[i]; for(int cnt = 1; cnt <= (jj + 1); cnt++) cur *= 2; dp[i][j] = min(dp[i][j], cur); } } //printf("dp[%d][%d]=%d\n", i, j, dp[i][j]); } } printf("%I64d\n", dp[0][n - 1]); } return 0; }
题目:POJ 3280 http://poj.org/problem?id=3280
代码:
#include <stdio.h> #include <string.h> #include <math.h> #include <algorithm> #define MOD 1000000007 #define INF 0x7fffffff - 20010 using namespace std; char s[2005]; int add[30], del[30], dp[2005][2005]; int main() { #ifdef LOCAL freopen("dpdata.txt", "r", stdin); #endif int n, m; char c; while(scanf("%d %d ", &n, &m) != EOF) { memset(add, 0, sizeof(add)); memset(del, 0, sizeof(del)); memset(dp, 0, sizeof(dp)); for(int i = 0; i <= m; i++) { for(int j = i + 1; j <= m; j++) { dp[i][j] = INF; } } scanf("%s", s); for(int i = 0; i < n; i++) { scanf(" %c", &c); scanf("%d%d", &add[c - 'a'], &del[c - 'a']); } for(int jj = 1; jj < m; jj++) { for(int i = 0; i + jj < m; i++) { int j = i + jj; if(s[i] != s[j]) { dp[i][j] = min(dp[i][j], dp[i + 1][j] + add[s[i] - 'a']); dp[i][j] = min(dp[i][j], dp[i][j - 1] + add[s[j] - 'a']); dp[i][j] = min(dp[i][j], dp[i + 1][j] + del[s[i] - 'a']); dp[i][j] = min(dp[i][j], dp[i][j - 1] + del[s[j] - 'a']); } else { dp[i][j] = min(dp[i][j], dp[i + 1][j - 1]); } //printf("dp[%d][%d] = %d\n", i, j, dp[i][j]); } } printf("%d\n", dp[0][m - 1]); } return 0; }
相关文章推荐
- 简单工厂模式
- I学霸官方免费教程四十六 :Java基础之序列化和反序列化
- POJ 3903 Stock Exchange 解题心得
- 文件管理与XMl、JSON解析
- hit2060 Fibonacci Problem Again
- HPOJ 1703: 此题乃神题,劝你别做
- 排序算法_C++(二)插入排序之折半插入排序
- hdu 1757 A Simple Math Problem
- Zipper(动态规划)
- Spring自动装配Bean属性
- Windows10放开Administrator权限
- [LeetCode] Find Peak Element
- Trie树 c++实现
- nodejs使用md5带秘钥加密
- POJ 3667 Hotel (线段树求最长连续子序列)
- 处理文本,提取数据的脚本-主要就是用sed
- ListFragment
- python pandas 如何对一列做四舍五入的操作
- HDU 3460 Ancient Printer (字典树)
- oc中的类别