https://oj.xjtuicpc.com/problem/1080
我大E了啊,没细想,一发模拟交上去被防出去,全防出去了啊(WA 0)。
其实是一道区间DP题(括号匹配挺多都是区间DP),我们用\(DP[i][j]\)表示第\(i\)位到第\(j\)位最少要填充几个。
转移过程就是套路枚举区间断点,用之前的结果拼成当前的答案,i,j,k枚举(区间DP常规套路),复杂度是\(O(n^3)\)的,珂以接受。
转移方程见代码,因为要分类讨论,比较烦。
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define inf 0x3f3f3f3f
using namespace std;
int dp[101][101];
int main(){
int i,j,k,n,ans=0;
char s[101];
freopen("T.in","r",stdin);
freopen("myans.out","w",stdout);
scanf("%s",s+1);
n=strlen(s+1);
for(i=1;i<=n;i++)
for(j=1;j<=n;j++)
if(i<=j) dp[i][j]=inf;
else dp[i][j]=0;
for(i=1;i<=n;i++){
dp[i][i]=1;
for(j=i-1;j>=1;j--){
for(k=j;k<i;k++){
if(s[i]==‘)‘){
if(s[k]==‘(‘) dp[j][i]=min(dp[j][i],dp[j][k-1]+dp[k+1][i-1]);
else dp[j][i]=min(dp[j][i],dp[j][k-1]+dp[k][i-1]+1);
}
else if(s[i]==‘]‘){
if(s[k]==‘[‘) dp[j][i]=min(dp[j][i],dp[j][k-1]+dp[k+1][i-1]);
else dp[j][i]=min(dp[j][i],dp[j][k-1]+dp[k][i-1]+1);
}
else{
dp[j][i]=min(dp[j][i],dp[j][k-1]+dp[k][i-1]+1);
}
}
}
}
ans=dp[1][n];
printf("%d",ans);
// system("pause");
return 0;
}
原文:https://www.cnblogs.com/landmine-sweeper/p/14262419.html