dp:FZU2030括号问题
给出一个字符串,其中包括3种字符: ‘(‘, ‘)’, ‘?’.其中?表示这个字符可以是’(‘也可以是’)’. 现在给出字符串S,你可以在’?’处填写’(‘ 或者 ‘)’,当然随意填写得到的序列可能是括号不匹配的。例如”(?”,如果你填写’(‘那么”((“是括号不匹配的! 现在你的任务是确定你有多少种填写方案,使得最终的字符串是括号匹配的!2种方案是不同的,当2种方案中至少存在1个填写字符是不同的。 例如,对于”((??))”,我们可以得到2种方案: “((()))”, “(()())”。
数据包含多组测试数据第一行输入一个字符串S(S的长度不超过16)。
输出一个整数,表示合法的填写方案数。
思路:可以用搜索做,这个题目数据很小,但是要是字符串长度为1000呢???那么就考虑dp吧。首先,它有三种状态,'(' ')' '?' 那么可以用dp[i][j]表示历遍到第i个字符,没有匹配的'('有j个的情况下的种数......那么题目就可以转化为,在历遍len个字符,没有匹配的'('有0个的情况下的种数.....dp[len][0]
对应状态,'('——dp[i][j]=dp[i-1][j-1] 在第i个字符为'('的情况下,种数就等于上一状态i-1个字符,j-1个'('的种数
')'——dp[i][j]=dp[i-1][j+1] 第i个字符为')'的时候,为匹配的')'肯定要-1,所以推导状态就是前一个未-1的状态
'?'——dp[i][j]=dp[i-1][j+1]+dp[i-1][j-1]
#include<iostream> #include<stdio.h> #include<string.h> using namespace std; int dp[1005][1005],len; char a[1005]; int main() { while(scanf("%s",a)>0) { memset(dp,0,sizeof(dp)); dp[0][1]=1; len=strlen(a); //for(int i=0;i<len;i++) //printf("%c",a[i]); for(int i=1;i<len;i++) { for(int j=0;j<len;j++) if(a[i]=='(') dp[i][j]=dp[i-1][j-1];//%1000000007; else if(a[i]==')') dp[i][j]=dp[i-1][j+1];//%1000000007; else dp[i][j]=(dp[i-1][j-1]+dp[i-1][j+1]);//%1000000007; } printf("%d\n",dp[len-1][0]); } return 0; }
朋友们,虽然这个世界日益浮躁起来,只要能够为了当时纯粹的梦想和感动坚持努力下去,不管其它人怎么样,我们也能够保持自己的本色走下去。