码迷,mamicode.com
首页 > 其他好文 > 详细

POJ 2955 Brackets 区间dp

时间:2015-12-21 21:33:49      阅读:127      评论:0      收藏:0      [点我收藏+]

标签:

按照合法匹配条件,找最大的匹配

一眼就是区间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;
}
View Code

 我的习惯性区间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;
}
View Code

 

POJ 2955 Brackets 区间dp

标签:

原文地址:http://www.cnblogs.com/shuguangzw/p/5064851.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!