题目链接:传送门
题目大意:中文题,略
题目思路:区间DP
这个题是问需要添加多少个括号使之成为合法括号序列,那么我们可以先求有多少合法的括号匹配,然后用字符串长度减去匹配的括号数就行
状态转移方程主要是对于我们枚举的区间 dp[i][j],如果 i 和 j 处的括号能够匹配,则dp[i][j]=dp[i+1][j-1]+1;
因为我们是从小到大枚举长度,所以小长度的区间一定是最优的,所以当 i 与 j 匹配时,则是子区间的最优值+1
#include <iostream> #include <cstdio> #include <cstdlib> #include <cmath> #include <algorithm> #include <cstring> #include <stack> #include <cctype> #include <queue> #include <string> #include <vector> #include <set> #include <map> #include <climits> #define lson root<<1,l,mid #define rson root<<1|1,mid+1,r #define fi first #define se second #define ping(x,y) ((x-y)*(x-y)) #define mst(x,y) memset(x,y,sizeof(x)) #define mcp(x,y) memcpy(x,y,sizeof(y)) using namespace std; #define gamma 0.5772156649015328606065120 #define MOD 1000000007 #define inf 0x3f3f3f3f #define N 100005 #define maxn 1050 typedef pair<int,int> PII; typedef long long LL; int n,m,cnt,temp,ans; char str[1000]; int dp[105][105]; int main(){ int i,j,group,Case=0; while(scanf("%s",str+1)!=EOF){ mst(dp,0); int len=strlen(str+1); for(int p=2;p<=len;++p) for(i=1;i<=len;++i){ j=i+p-1;if(j>len)break; if((str[i]==‘(‘&&str[j]==‘)‘)||(str[i]==‘[‘&&str[j]==‘]‘))dp[i][j]=dp[i+1][j-1]+1; for(int k=i;k<j;++k){ dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]); } } printf("%d\n",len-dp[1][len]*2); } return 0; }
时间: 2024-10-19 17:01:05