구간 dp 학습편 (괄호 일치)

2291 단어 구간 dp
괄호 일치, 제목 요구에 따라 최대 괄호 일치수 구하기
HRBUST - 1834
예를 들어 이 문제는 석자 합병과 달리 제목이 정한 괄호의 일치 상황은 우리가 스스로 갱신해야 한다. 석자 합병에서 정한 수치와 직접적이지 않다. 이것은 우리가 이전의 상태 이동 방정식(dp[i][j]=max(dp[i][j], dp[i][k]+dp[k+1][j])을 갱신하기 전에 현재 구간의 괄호 일치 상황을 갱신하는 판별식(s[i]=s[j]?2:0)을 추가해야 한다.이렇게 하면 더 큰 구간을 갱신하는 동시에 가장 좋은 결과를 찾을 수 있다
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int dp[105][105];
int main()
{
    char a[105];
    while(scanf("%s",a) != EOF)
    {
        int n = strlen(a);
        memset(dp, 0, sizeof(dp));
        for(int len = 1; len < n; len ++)
            for(int i = 0; i + len < n; i ++)
        {
            int j = len + i;
            if((a[i] == '(' && a[j] == ')')|| (a[i] == '[' && a[j] == ']'))
                dp[i][j] = dp[i+1][j-1] + 2;
            for(int k = i; k < j; k ++)
                dp[i][j] = max(dp[i][k]+dp[k+1][j],dp[i][j]);
        }
        printf("%d
",dp[0][n-1]); } return 0; }

괄호 일치(둘)
괄호가 일치합니다.같다
괄호를 얼마나 넣어야 완전히 일치하는지 묻고 마지막 출력을 (n-dp[0][n-1])으로 바꾸면 됩니다.
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
int dp[105][105];
int main()
{
    char a[105];
    int t;
    scanf("%d",&t);
    while(t --)
    {
        scanf("%s",a);
        int n = strlen(a);
        memset(dp, 0, sizeof(dp));
        for(int len = 1; len < n; len ++)
            for(int i = 0; i + len < n; i ++)
        {
            int j = len + i;
            if((a[i] == '(' && a[j] == ')')|| (a[i] == '[' && a[j] == ']'))
                dp[i][j] = dp[i+1][j-1] + 2;
            for(int k = i; k < j; k ++)
                dp[i][j] = max(dp[i][k]+dp[k+1][j],dp[i][j]);
        }
        printf("%d
",n - dp[0][n-1]); } return 0; }

좋은 웹페이지 즐겨찾기