hrbust 哈理工oj 1834 括号匹配【好题】【floyd+dp】

本文介绍了一种求解括号序列最大匹配数的问题,通过动态规划和Floyd算法优化解决方案,提供了一个高效的AC代码示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

括号匹配
Time Limit: 1000 MSMemory Limit: 32768 K
Total Submit: 133(51 users)Total Accepted: 39(28 users)Rating: Special Judge: No
Description
给出一个括号序列括号类型包括'(',')','[',']'求最大的括号匹配数。
Input
本题有多组测试数据。每组数据是一个长度不超过100的括号序列。
Output
最大的括号匹配数
Sample Input
((()))
()()()
([]])
)[)(
([][][)
Sample Output
6
6
4
0
6

直接用两层for的方法来记录匹配括号成功数来求结果的话,并不属于最优解。两层for可以用来判断括号是否匹配,但是不能得到最优匹配数。

既然想到了动态规划,那么最首先需要想到的东西是所有情况都扫到、这里我们这样来完成:

两层for,外层控制匹配长度changdu,内层for控制起始位子i、那么如果我们设j=i+changdu,并且a【i】和a【j】符合括号匹配的情况的话,我们这里可以得到这样的动态规划转移方程:
dp【i】【j】=dp【i+1】【j-1】+1(表示我们得到了一组匹配。)//这里的dp【i】【j】表示从i开始到j的这段子串最优匹配数,(最大匹配数)。

我们这里的思路只能保证把一些个情况列举出来,比如样例中的第一组样例:

((())),在状态转移的过程中,因为中间括号有匹配上,而且在+1的时候,带上了中间匹配上的+1,所以能一直+1,这个加到最后得到的是3,最终结果确实能得到6、但是如果变成了第二组样例那样,()()(),明显+1的时候都是在0上加的,不像上一种情况会在1的基础上+1、那怎么办才行呢?

使用floyd思维递推关系、

如果dp【i】【j】+dp【j】【k】>dp【j】【k】,那么dp【j】【k】=dp【i】【j】+dp【j】【k】、很容易就把问题解决了。

AC代码:

#include<stdio.h>
#include<string.h>
#include<iostream>

using namespace std;
int dp[101][101];
int main()
{
    char a[105];
    while(~scanf("%s",a))
    {
        memset(dp,0,sizeof(dp));
        int n=strlen(a);
        for(int changdu=1;changdu<n;changdu++)
        {
            for(int i=0;i+changdu<n;i++)
            {
                int j=i+changdu;
                if(a[i]=='('&&a[j]==')'||a[i]=='['&&a[j]==']')
                {
                    dp[i][j]=dp[i+1][j-1]+1;
                }
                for(int k=0;k<n;k++)
                {
                    dp[i][j]=max(dp[i][j],dp[i][k]+dp[k+1][j]);
                }
            }
        }
        printf("%d\n",dp[0][n-1]*2);
    }
}










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值