• 最小添加括号数 dp记忆化


    题目:

    输入括号

    输入:(注意有空行,用getline()或者gets()输入)

    ([(]

    ([(((])))

    []]]]]

     

    )))(((

    要求输出最小要加入的括号数目

    分析:

       经典dp题,如果用dp自底向上的递推做的话,比较麻烦,其实用记忆化做很简单,

       每次递归前加上判断是否已经计算过即可减少计算量,相当于dfs里的剪枝,代码如下

     

    #include <iostream>

    #include <string>

    #include <cstring>

    using namespace std;

    #define X 205

    #define INF 1000

    int dp[X][X];

    string s;

    int f(int i,int j) //记忆化

    {

       if(dp[i][j]!=-1)            //当计算过时

          return dp[i][j];

       if(i>j)                     //当前面的指针大于后面的指针时,已经结束这次递归

          return 0;

       if(i==j)                 //恰巧相等时,加一

          return 1;

       int ans = INF;

       if((s[i]=='('&&s[j]==')')||(s[i]=='['&&s[j]==']'))

          ans = min(ans,f(i+1,j-1));  //当两者恰好能组成一对括号时

       else if(s[i]=='('||s[i]=='[')

          ans = min(ans,f(i+1,j)+1);  //当只有左边的一半时

       else if(s[j]==')'||s[j]==']')

          ans = min(ans,f(i,j-1)+1);  //当之有右边的一半时

       for(int k=i;k<j;k++)        //相当于最短路时的松弛操作

          ans = min(ans,f(i,k)+f(k+1,j));

       dp[i][j] = ans;             //用辅助数组储存状态,思想为用空间换取时间

       return ans;

    }

    int main()

    {

       freopen("sum.in","r",stdin);

       freopen("sum.out","w",stdout);

       while(getline(cin,s))

       {

          memset(dp,-1,sizeof(dp));

          if(s.size())    //注意到有空行

             cout<<f(0,s.size()-1)<<endl;

          else

             cout<<endl;

       }

       return 0;

    }

  • 相关阅读:
    Python在信号与系统(1)——Hilbert兑换,Hilbert在国家统计局的包络检测应用,FIR_LPF滤波器设计,格鲁吉亚也迫使高FM(PM)调制
    HDU 4925 Apple Tree
    [ACM] HDU 3395 Special Fish (最大重量二分图匹配,KM算法)
    OCP解决问题053-16 MEMORY_TARGET
    图像归一化
    我毕业10年
    静态分析与动态分析
    逐步求精
    抽象与逐步求精
    自项向下,逐步求精
  • 原文地址:https://www.cnblogs.com/yejinru/p/2405463.html
Copyright © 2020-2023  润新知