按照合法匹配条件,找最大的匹配
一眼就是区间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
