首页 > 其他 > 详细

[USACO07OPEN]Cheapest Palindrome G

时间:2020-04-12 18:24:50      阅读:52      评论:0      收藏:0      [点我收藏+]

\(\large{题目链接}\)
\(\\\)
\(\Large\textbf{Solution: } \large{考虑区间dp。设f_{i,j}表示\left[ i,j\right] 构成回文的最小价值。\\如果c_i = c_j那么f_{i,j} = \min (f_{i, j}, f_{i+1,j-1})。然后考虑一般情况,要么f_{i,j}从f_{i + 1,j}转移过来,增加或者删去i,反之一样。}\)
\(\\\)
\(\Large\textbf{Summary: } \large{区间dp有几种转移方式。\\1. f_{i,j}由f_{i,k}和f_{k + 1,j}转移过来。这个时候需要外层由小到大枚举区间长度,内层枚举起点,最里层枚举断点,转移即可。\\2.f_{i,j}由f_{i + 1,j}和f_{i,j - 1}转移过来,此时只需枚举区间长度与起点即可。}\)
\(\\\)
\(\Large\textbf{Code: }\)

#include <bits/stdc++.h>
using namespace std;

const int N = 2005;

int n, m, a[N], b[N], f[N][N];
char c[N], x[N];

int main() {
	scanf("%d%d%s", &n, &m, c + 1);
	int u, v;
	for (int i = 1; i <= n; ++i) scanf("%s%d%d", x, &u, &v), a[x[0] - ‘a‘] = u, b[x[0] - ‘a‘] = v;
	memset(f, 0x3f, sizeof (f));
	for (int i = 0; i <= m; ++i) f[i][i] = 0;
	for (int i = 0; i <= m; ++i) for (int j = 0; j < i; ++j) f[i][j] = 0;
	for (int k = 1; k <= m; ++k) {
		for (int i = 1; (i + k) <= m; ++i) {
			int j = i + k;
			if (c[i] == c[j]) f[i][j] = min(f[i][j], f[i + 1][j - 1]);
			f[i][j] = min(f[i][j], f[i + 1][j] + min(a[c[i] - ‘a‘], b[c[i] - ‘a‘]));
			f[i][j] = min(f[i][j], f[i][j - 1] + min(a[c[j] - ‘a‘], b[c[j] - ‘a‘]));
		}
	}
	cout << f[1][m] << endl;
	return 0;
} 

[USACO07OPEN]Cheapest Palindrome G

原文:https://www.cnblogs.com/Miraclys/p/12686276.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!