涉及的递归调用究竟发生了什么?

时间:2015-11-06 12:10:35

标签: c++ algorithm recursion dynamic-programming

所以,我试图解决以下问题:http://www.spoj.com/problems/MREPLBRC/en/

常规括号序列是一串字符,仅包含左括号和右括号,并满足以下条件:

•空字符串是常规括号序列。

•如果A是常规的bracket0序列,则(A),[A]和{A}也是常规括号序列。

•如果A和B是常规括号序列,则AB也是常规括号序列。

例如,序列[({})],{} i {} [{}]是常规的,但序列[({{([,}和[{}])([{}]是不

Ivica找到了一个看起来像是常规括号序列的字符串。有些角色变得污迹化,难以辨认,可能是任何角色。

编写一个程序,计算字符串中的字符串可以被括号替换的方式,以便结果是常规括号序列。这个数字可能非常大,因此只输出最后5位数字。

输入

第一行包含偶数整数N(2 <= N <= 200),即字符串的长度。

第二行包含字符串。难以理解的字符由&#39;?&#39;表示。字符。

输出

输出字符串可以读取的常规括号序列的数量。

经过多次思考,我无法真正形成解决方案,因此,我试图寻找解决方案。我在这里找到了它:http://ruhinraihan.blogspot.in/2012/08/spoj-4038-counting-way-of-bracket.html

以下是此代码:

#include<iostream>
#include<list>
#include<string>
#include<cstring>
#include<sstream>
#include<cctype>
#include<string.h>
#include<algorithm>
#include<cmath>
#include<stack>
#include<fstream>
#include<cstdlib>
#include<vector>
#include<map>
#include<utility>
#include<iomanip>
#include<queue>

using namespace std;

#define INF (1<<29)
#define SET(a) memset(a,-1,sizeof(a))
#define ALL(a) a.begin(),a.end()
#define CLR(a) memset(a,0,sizeof(a))
#define FILL(a,v) memset(a,v,sizeof(a))
#define PB push_back
#define FOR(i,n) for(int i = 0;i<n;i++)
#define PI acos(-1.0)
#define EPS 1e-9
#define MP(a,b) make_pair(a,b)
#define READ(f) freopen(f, "r", stdin)
#define WRITE(f) freopen(f, "w", stdout)
#define LL long long
#define MOD 100000

bool moduloUsed;
LL memo[200+10][200+10];
string s;

LL func(int left, int right)
{
    int i, valid;
    if(left>right)  return 1;

    if(memo[left][right]!=-1)   return memo[left][right];

    LL ret=0;

    for(i=left+1;i<=right;i+=2)
    {
        if(s[left]=='(' && s[i]==')') valid=1;
        else if(s[left]=='{' && s[i]=='}') valid=1;
        else if(s[left]=='[' && s[i]==']') valid=1;
        else if(s[left]=='?' && s[i]==')') valid=1;
        else if(s[left]=='?' && s[i]=='}') valid=1;
        else if(s[left]=='?' && s[i]==']') valid=1;
        else if(s[left]=='(' && s[i]=='?') valid=1;
        else if(s[left]=='{' && s[i]=='?') valid=1;
        else if(s[left]=='[' && s[i]=='?') valid=1;
        else if(s[left]=='?' && s[i]=='?') valid=3;
        else    valid=0;

        ret+=valid*func(left+1,i-1)*func(i+1,right);

        if(ret>MOD)
        {
            moduloUsed=true;
            ret%=MOD;
        }
    }
return memo[left][right]=ret;
}


int main()
{
    LL ans,length;

    while(cin>>length>>s)
    {
        SET(memo);
        ans=func(0,length-1);
        if(!moduloUsed)
        cout<<ans<<endl;
        else
        printf("%05lld\n",ans);
    }

return 0;
}

我想知道,函数fun到底发生了什么。我知道它遍历输入字符串,并检查平衡括号条件的可能组合,然后,func(left+1,i-1)*func(i+1,right),这两个递归调用代表什么?请帮我。

1 个答案:

答案 0 :(得分:1)

基本上,通过将任何open + close括号对的所有有效组合相乘来达到答案。 long winded if语句是递归函数的停止条件,因为任何一对都可以有0,1或3个有效组合。抛出你的递归调用实际上(与for循环结合)扫描整个字符串以获得括号对。如果说这个字符串是对称的,那就更简单了:fun(left + 1, right -1)