【区间DP first】POJ 2955 Brackets

POJ 2955 Brackets 

如果s[st] == s[ed],那么dp[st][ed] = dp[st + 1][ed - 1] + 2。(这个放在枚举断点之前)其实想想确实是这样的,两端相等,那么就该初始化为去头去尾的中间的子串的dp值再加上2

然后就开始枚举断点,更新dp为尽可能的大,大区间等于两个小区间相加

区间DP的一般步骤:

枚举长度

枚举起点

枚举断点(更新dp)

#include <iostream>
#include <algorithm>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <limits>
#include <set>
#include <queue>
#include <vector>
#include <stack>
#include <map>
#define INF 0x3f3f3f3f

using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxN = 100 + 5;

string s;
int dp[maxN][maxN];
void init()
{
    memset(dp, 0, sizeof(dp));
}
int main()
{
    while(cin >> s)
    {
        if(s == "end")
            break;
        int n = s.size();
        init();
        for(int len = 2; len <= n; len ++ )//枚举长度
        {
            for(int st = 0; st < n; st ++ )//枚举起点
            {
                int ed = st + len - 1;
                if(ed >= n) break;
                int add = 0;
                if(s[st] == '(' && s[ed] == ')')
                    add ++;
                if(s[st] == '[' && s[ed] == ']')
                    add ++;
                if(add)
                    dp[st][ed] = dp[st + 1][ed - 1] + 2;
                for(int mid = st; mid <= ed - 1; mid ++ )//枚举断点
                {
                    dp[st][ed] = max(dp[st][ed], dp[st][mid] + dp[mid + 1][ed]);
                }
            }
        }
        printf("%d\n", dp[0][n - 1]);
    }
    return 0;
}
发布了180 篇原创文章 · 获赞 54 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44049850/article/details/103865465