poj 1141 Brackets Sequence dp

本文介绍了一种使用递归和记忆化搜索方法优化规则字符串的算法。该算法通过动态规划求解将任意字符串转换为规则字符串的最短路径,并记录达到最优解的分割方式。适用于需要最小化规则字符串表示的应用场景。
这个题目用递归描述的规则字符串
那很正常的就想到用递归的方式来求解
然后很明显的有重叠子问题,并且满足最优子结构
所以就想到用记忆化搜索的方法来求解
dp[i][j]表示把i到j这一串变成规则的字符串后的最短长度
求解的时候顺道把取得最优解的方式保留下来就ok了 保留在哪分割,或者是前后匹配
#include
#include
#include
using namespace std;
const int maxn=111,inf=99999999;
char a[maxn];
int dp[maxn][maxn],ans[maxn][maxn];
int text[maxn][maxn];

int dfs(int t,int s)
{
    if(text[t][s]) return(0);
    if(t>s) {dp[t][s]=0;return(0);}
    if(t==s)
    {
        dp[t][s]=2;
        ans[t][s]=t;
    }
    for(int i=t;i
    {
        dfs(t,i);
        dfs(i+1,s);
        if(dp[t][i]+dp[i+1][s]
        {
            dp[t][s]=dp[t][i]+dp[i+1][s];
            ans[t][s]=i;
        }
    }
    if((a[t]=='['&&a[s]==']')||(a[t]=='('&&a[s]==')'))
    {
        dfs(t+1,s-1);
        if(dp[t+1][s-1]+2
        {
            dp[t][s]=dp[t+1][s-1]+2;
            ans[t][s]=0;
        }
    }
    text[t][s]=1;
    return(0);
}

int prin(int t,int s)
{
//    printf("%d %d\n",t,s);
    if(t>s) return(0);
    if(t==s)
    {
        if(a[t]==']'||a[t]=='[')
        printf("[]");
        else
        printf("()");
        return(0);
    }
    if(ans[t][s]==0)
    {
        printf("%c",a[t]);
        prin(t+1,s-1);
        printf("%c",a[s]);
        return(0);
    }
    else
    {
        prin(t,ans[t][s]);
        prin(ans[t][s]+1,s);
    }
    return(0);
}


int main()
{
//    freopen("in.txt","r",stdin);

    {
        int lon=0;
        while(scanf("%s",&a[lon+1])!=EOF)
        {
            lon=strlen(&a[1]);
        }

        memset(text,0,sizeof(text));
        for(int i=0;i<=maxn;i++)
        for(int j=0;j<=maxn;j++)
        dp[i][j]=inf;
        dfs(1,lon);
        prin(1,lon);
        printf("\n");
//        printf("%d\n",dp[1][lon]);
        memset(a,0,sizeof(a));
        memset(ans,0,sizeof(ans));
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值