文章首发于公众号面鲸,欢迎关注~
第一题
题目描述
现在给你一个只包含""括号的字符串,问你至少加多少个字符是合法的,对于字符串合法的定义为:
- 字符串为空是合法的
- 若字符串A合法,则字符串(A), [A]也是合法的
- 若字符串A和字符串B均合法,则AB合法
输入
- 第一行输入一个字符串s,保证只有题目要求的字符
- 1 <= len(s) <= 200
输出
- 输出最少需要添加几个字符可以构成合法的字符串
样例输入
样例输出
- 1
样例输入
- )(][][)(
样例输出
- 3
分析
- 如果只有一种括号的话就是leetcode921的原题
- 有2种括号的话需要用DP去搞。我们先求出来通过添加字符,从i到j能构成的合法串的最短长度是多少。然后状态转移一波(分情况讨论)。
解法
#include <bits/stdc++.h>
using namespace std;
int dp[205][205];
int main(){
string s;
int i,j,k,p;
while(cin>>s){
memset(dp,0,sizeof(dp));
if(s.size()==1){
puts("1");
continue;
}
for(i=0;i+1<s.size();i++){
if((s[i]=='('&&s[i+1]==')')||(s[i]=='['&&s[i+1]==']'))
dp[i][i+1]=2;
}
for(i=3;i<=s.size();i++){
for(j=0;j+i-1<s.size();j++){
k=j+i-1;
dp[j][k]=max(dp[j][k],dp[j+1][k-1]);
dp[j][k]=max(dp[j][k],max(dp[j+1][k],dp[j][k-1]));
if((s[j]=='('&&s[k]==')')||(s[j]=='['&&s[k]==']')){
dp[j][k]=max(dp[j][k],dp[j+1][k-1]+2);
}
for(p=j+1;p<k;p++){
dp[j][k]=max(dp[j][k],dp[j][p]+dp[p+1][k]);
}
}
}
cout<<s.si