1.dp定义:最小操作数
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1005;
int dp[N][N];
const int INF = 1e9;
string s;
bool is_match(int i, int j)
{
if (s[i] == '[' && s[j] == ']')
return true;
if (s[i] == '(' && s[j] == ')')
return true;
return false;
}
int main()
{
cin >> s;
int n = s.size();
for(int len=1;len<=n;len++)
for (int i = 0;i + len - 1 < n;i++)
{//len=1,j==i的时候,把所有dp[i][j]都赋予了最大值
int j = i + len - 1;
dp[i][j] = INF;
if (j >= 1)
{
if (is_match(i, j)) //能够匹配上
{
dp[i][j] = dp[i + 1][j - 1];
}
//左边各插入一个括号,比较操作最小值
dp[i][j] = min(dp[i][j], min(dp[i + 1][j], dp[i][j - 1]) + 1);
}
for (int k = i;k < j;k++)
{ //寻找中间断点
dp[i][j] = min(dp[i][j], dp[i][k] + dp[k + 1][j]);
}
}
cout << dp[0][n - 1];
}
2.dp定义:最多匹配括号数
#include <iostream>
#include <algorithm>
using namespace std;
const int N = 1005;
int dp[N][N];
const int INF = 1e9;
string s;
bool is_match(int i, int j)
{
if (s[i] == '[' && s[j] == ']')
return true;
if (s[i] == '(' && s[j] == ')')
return true;
return false;
}
int main()
{
cin >> s;
int n = s.size();
for(int i=n-2;i>=0;i--)
for (int j = i;j < n;j++)
{
if (is_match(i, j))
//左右相等,匹配数+2
dp[i][j] = dp[i + 1][j - 1] + 2;
else
{ //左右端各放入一个
dp[i][j] = max(dp[i][j - 1], dp[i + 1][j]);
}
//寻找中断点
for (int k = i;k < j;k++)
dp[i][j] = max(dp[i][j], dp[i][k] + dp[k + 1][j]);
}
cout << n-dp[0][n - 1];
}
密码脱落,括号匹配这种题目,使用先求最大值,运用结果算出最小操作数更好,因为dp数组定义为求最小值的话,需要将数组合理的初始化,容易出错