FZU2030 括号问题(dp)

Problem 2030 括号问题

Accept: 398    Submit: 753
Time Limit: 1000 mSec    Memory Limit : 32768 KB

 Problem Description

给出一个字符串,其中包括3种字符: ‘(‘, ‘)’, ‘?’.其中?表示这个字符可以是’(‘也可以是’)’. 现在给出字符串S,你可以在’?’处填写’(‘ 或者 ‘)’,当然随意填写得到的序列可能是括号不匹配的。例如”(?”,如果你填写’(‘那么”((“是括号不匹配的! 现在你的任务是确定你有多少种填写方案,使得最终的字符串是括号匹配的!2种方案是不同的,当2种方案中至少存在1个填写字符是不同的。 例如,对于”((??))”,我们可以得到2种方案: “((()))”, “(()())”。

 Input

数据包含多组测试数据 第一行输入一个字符串S(S的长度不超过16)。

 Output

输出一个整数,表示合法的填写方案数。

 Sample Input

((??))

 Sample Output

2

思路: dp[i][j]表示第i个位置左右括号抵消后左括号剩下的数量,dp[sz][0]就是答案了

#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int INF = 1e9;
const double eps = 1e-6;
const int N = 20;
int cas = 1;

char s[N];
int dp[N][N];

void run()
{
    int sz = strlen(s+1);
    memset(dp,0,sizeof(dp));
    dp[0][0]=1;
    for(int i=1;i<=sz;i++)
    {
        if(s[i]==‘(‘ || s[i]==‘?‘)
        {
            for(int j=1;j<=sz;j++)
                dp[i][j]+=dp[i-1][j-1];
        }
        if(s[i]==‘)‘ || s[i]==‘?‘)
        {
            for(int j=0;j<=sz;j++)
                dp[i][j]+=dp[i-1][j+1];
        }
    }
//    for(int i=1;i<=sz;i++)
//    {
//        for(int j=1;j<=sz;j++) cout<<dp[i][j]<<‘ ‘;
//        cout<<endl;
//    }
    printf("%d\n",dp[sz][0]);
}

int main()
{
    #ifdef LOCAL
    //freopen("case.txt","r",stdin);
    #endif
    while(scanf("%s",s+1)!=EOF)
        run();
    return 0;
}
时间: 2024-10-27 00:34:16

FZU2030 括号问题(dp)的相关文章

Neko and Aki&#39;s Prank CodeForces - 1152D (括号序列,dp)

大意: 将所有长度为2*n的合法括号序列建成一颗trie树, 求trie树上选出一个最大不相交的边集, 输出边集大小. 最大边集数一定不超过奇数层结点数. 这个上界可以通过从底层贪心达到, 所以就转化为求奇数层结点数. 然后就dp求出前$i$为'('比')'多j个的方案数, 奇数层且合法的时候统计一下贡献即可. #include <iostream> #include <iostream> #include <algorithm> #include <cstdio

括号匹配问题 区间DP经典问题

题目链接 http://acm.nyist.edu.cn/JudgeOnline/problem.php?pid=15 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来.如:[]是匹配的([])[]是匹配的((]是不匹配的([)]是不匹配的 分析:要求要添加多少个,可以求出最大匹配的长度,这样剩下的都是没有匹配的,所以每个对于一个匹配就可以了. 即 答案 =

DP总结 ——QPH

常见优化 单调队列 形式 dp[i]=min{f(k)} dp[i]=max{f(k)} 要求 f(k)是关于k的函数 k的范围和i有关 转移方法 维护一个单调递增(减)的队列,可以在两头弹出元素,一头压入元素. 队列中维护的是两个值.一个是位置,这和k的范围有关系,另外一个是f(k)的值,这个用来维护单调性,当然如果f(k)的值可以利用dp值在O(1)的时间内计算出来的话队列中可以只维护一个表示位置的变量. 枚举到一个i的时候,首先判断队首元素的位置是否已经不满足k的范围了,如果不满足就将队首

动态规划(2)--括号匹配(二)

括号匹配(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:6 描述给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来.如:[]是匹配的([])[]是匹配的((]是不匹配的([)]是不匹配的 输入 第一行输入一个正整数N,表示测试数据组数(N<=10)每组测试数据都只有一行,是一个字符串S,S中只包含以上所说的四种字符,S的长度不超

集训第五周动态规划 J题 括号匹配

Description We give the following inductive definition of a “regular brackets” sequence: the empty sequence is a regular brackets sequence, if s is a regular brackets sequence, then (s) and [s] are regular brackets sequences, and if a and b are regul

NYOJ15括号匹配

NYOJ15括号匹配 括号匹配(二) 时间限制:1000 ms  |  内存限制:65535 KB 难度:6 描述 给你一个字符串,里面只包含"(",")","[","]"四种符号,请问你需要至少添加多少个括号才能使这些括号匹配起来.如:[]是匹配的([])[]是匹配的((]是不匹配的([)]是不匹配的 输入 第一行输入一个正整数N,表示测试数据组数(N<=10)每组测试数据都只有一行,是一个字符串S,S中只包含以上所说

LeetCode之“动态规划”:Longest Valid Parentheses

题目链接 题目要求: Given a string containing just the characters '(' and ')', find the length of the longest valid (well-formed) parentheses substring. For "(()", the longest valid parentheses substring is "()", which has length = 2. Another e

记忆化搜索+DFS URAL 1183 Brackets Sequence

题目传送门 1 /* 2 记忆化搜索+DFS:dp[i][j] 表示第i到第j个字符,最少要加多少个括号 3 dp[x][x] = 1 一定要加一个括号:dp[x][y] = 0, x > y; 4 当s[x] 与 s[y] 匹配,则搜索 (x+1, y-1); 否则在x~y-1枚举找到相匹配的括号,更新最小值 5 */ 6 #include <cstdio> 7 #include <algorithm> 8 #include <cmath> 9 #include

UVa 1626 Brackets sequence (动态规划)

题意:用最少的括号将给定的字符串匹配,输出最优解.可能有空行. 思路:dp. dp[i][j]表示将区间i,j之间的字符串匹配需要的最少括号数,那么 如果区间左边是(或[,表示可以和右边的字符串匹配,枚举中间断点k,如果str[i]==str[k]则dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k+1][j])表示不需要加入新的括号,也可以插入新的括号则dp[i][j]=min(dp[i][j],dp[i+1][k]+dp[k+1][j]+1). 如果区间最左边字符