[区间DP练习] 求最长回文(不必连续)
1222. 密码脱落 - AcWing题库https://www.acwing.com/problem/content/1224/
X星球的考古学家发现了一批古代留下来的密码。
这些密码是由A、B、C、D 四种植物的种子串成的序列。
仔细分析发现,这些密码串当初应该是前后对称的(也就是我们说的镜像串)。
由于年代久远,其中许多种子脱落了,因而可能会失去镜像的特征。
你的任务是:
给定一个现在看到的密码串,计算一下从当初的状态,它要至少脱落多少个种子,才可能会变成现在的样子。
输入格式
共一行,包含一个由大写字母ABCD构成的字符串,表示现在看到的密码串。
输出格式
输出一个整数,表示至少脱落了多少个种子。
数据范围
输入字符串长度不超过1000
输入样例1:
ABCBA
输出样例1:
0
输入样例2:
ABDCDCBABC
输出样例2:
3
#include <cstdio>
#include <string.h>
using namespace std;
const int N = 1010;
int f[N][N];
char s[N];
int main()
{
scanf("%s", s);
int n = strlen(s);
for(int i = 1; i <= n; i ++)
{
for(int l = 0; l+i-1 < n; l ++)
{
int r = l+i-1;
if(i == 1) f[l][l] = 1;
else{
if(s[l] == s[r]) f[l][r] = f[l+1][r-1]+2;
if(f[l+1][r] > f[l][r]) f[l][r] = f[l+1][r];
if(f[l][r-1] > f[l][r]) f[l][r] = f[l][r-1];
}
}
}
printf("%d", n-f[0][n-1]);
return 0;
}
1070. 括号配对 - AcWing题库https://www.acwing.com/problem/content/1072/
Hecy 又接了个新任务:BE 处理。
BE 中有一类被称为 GBE。
以下是 GBE 的定义:
- 空表达式是 GBE
- 如果表达式 A 是 GBE,则 [A] 与 (A) 都是 GBE
- 如果 A 与 B 都是 GBE,那么 AB 是 GBE
下面给出一个 BE,求至少添加多少字符能使这个 BE 成为 GBE。
注意:BE 是一个仅由(
、)
、[
、]
四种字符中的若干种构成的字符串。
输入格式
输入仅一行,为字符串 BE。
输出格式
输出仅一个整数,表示增加的最少字符数。
数据范围
对于所有输入字符串,其长度小于100。
输入样例:
[])
输出样例:
1
法一(直接求最小):
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110, INF = 1e8;
int f[N][N];
string s;
bool check(int l, int r)
{
if(s[l] == '[' && s[r] == ']') return true;
if(s[l] == '(' && s[r] == ')') return true;
return false;
}
int main()
{
cin >> s;
int n = s.size();
for(int len = 1; len <= n; len ++)
{
for(int l = 0; l+len-1 < n; l ++)
{
int r = l+len-1;
f[l][r] = INF;
if(check(l,r)) f[l][r] = f[l+1][r-1];
if(r) f[l][r] = min(f[l][r], min(f[l+1][r], f[l][r-1])+1);
for(int k = l; k < r; k ++)
f[l][r] = min(f[l][r], f[l][k]+f[k+1][r]);
}
}
cout << f[0][n-1];
return 0;
}
法二(先求最大可以匹配的数量):
#include <iostream>
#include <cstring>
#include <algorithm>
using namespace std;
const int N = 110, INF = 1e8;
int f[N][N];
string s;
bool check(int l, int r)
{
if(s[l] == '[' && s[r] == ']') return true;
if(s[l] == '(' && s[r] == ')') return true;
return false;
}
int main()
{
cin >> s;
int n = s.size();
for(int len = 2; len <= n; len ++)
{
for(int l = 0; l+len-1 < n; l ++)
{
int r = l+len-1;
if(check(l,r)) f[l][r] = f[l+1][r-1]+2;
for(int k = l; k < r; k ++)
f[l][r] = max(f[l][r], f[l][k]+f[k+1][r]);
}
}
cout << n-f[0][n-1];
return 0;
}
本文来自博客园,作者:泥烟,CSDN同名, 转载请注明原文链接:https://www.cnblogs.com/Knight02/p/16027290.html