按照合法匹配条件,找最大的匹配
一眼就是区间dp 也知道dp[i][j]表示i-j中最大的匹配
但是状态转移方程怎么写呢??
其实对于这个题,感觉有很多种写法,看过网上的各种各样的题解,强烈Orz~
思路:
还是倒着dp,更新dp[i][j],有两种情况
1:当前字符不在最佳匹配中,dp[i][j]=dp[i+1][j];
2:当前字符在最佳匹配中,dp[i][j]=max(dp[i][j],dp[i][k-1]+dp[k+1][j]+2),前提条件是i位置和k位置匹配成功
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cstdlib> #include<cmath> using namespace std; typedef long long LL; int dp[105][105]; char s[105]; int main() { while(~scanf("%s",s+1)) { if(s[1]=='e')break; int n=strlen(s+1); memset(dp,0,sizeof(dp)); for(int i=n-1;i>=1;--i) { for(int j=i+1;j<=n;++j) { dp[i][j]=dp[i+1][j]; for(int k=i+1;k<=j;++k) if((s[i]=='('&&s[k]==')')||(s[i]=='['&&s[k]==']')) dp[i][j]=max(dp[i][j],dp[i+1][k-1]+dp[k+1][j]+2); } } printf("%d\n",dp[1][n]); } return 0; }
我的习惯性区间dp写法(只是看着顺眼,上一种其实也行,我有强迫症)
#include<cstdio> #include<cstring> #include<algorithm> #include<iostream> #include<cstdlib> #include<cmath> using namespace std; typedef long long LL; int dp[105][105]; char s[105]; int main() { while(~scanf("%s",s+1)) { if(s[1]=='e')break; int n=strlen(s+1); memset(dp,0,sizeof(dp)); for(int k=1;k<n;++k) { for(int i=1;i+k<=n;++i) { dp[i][i+k]=dp[i+1][i+k]; for(int j=i+1;j<=i+k;++j) if((s[i]=='('&&s[j]==')')||(s[i]=='['&&s[j]==']')) dp[i][i+k]=max(dp[i][i+k],dp[i+1][j-1]+dp[j+1][i+k]+2); } } printf("%d\n",dp[1][n]); } return 0; }
来源:https://www.cnblogs.com/shuguangzw/p/5064851.html