关闭

UVA题目10157 - Expressions(DP+高精度)

183人阅读 评论(0) 收藏 举报
分类:
Let X be the set of correctly built parenthesis expressions. The elements of X are strings consisting only
of the characters ‘(’ and ‘)’. The set X is defined as follows:
• an empty string belongs to X
• if A belongs to X, then (A) belongs to X
• if both A and B belong to X, then the concatenation AB belongs to X.
For example, the following strings are correctly built parenthesis expressions (and therefore belong
to the set X):
()(())()
(()(()))
The expressions below are not correctly built parenthesis expressions (and are thus not in X):
(()))(()
())(()
Let E be a correctly built parenthesis expression (therefore E is a string belonging to X).
The length of E is the number of single parenthesis (characters) in E.
The depth D(E) of E is defined as follows:
D(E) =



0 if E is empty
D(A) + 1 if E = (A), and A is in X
max(D(A), D(B)) if E = AB, and A, B are in X
For example, the length of “()(())()” is 8, and its depth is 2. What is the number of correctly
built parenthesis expressions of length n and depth d, for given positive integers n and d?
Write a program which
• reads two integers n and d
• computes the number of correctly built parenthesis expressions of length n and depth d;
Input
Input consists of lines of pairs of two integers - n and d, at most one pair on line, 2 ≤ n ≤ 300,
1 ≤ d ≤ 150.
The number of lines in the input file is at most 20, the input may contain empty lines, which you
don’t need to consider.
Output
For every pair of integers in the input write single integer on one line - the number of correctly built
parenthesis expressions of length n and depth d.
Note: There are exactly three correctly built parenthesis expressions of length 6 and depth 2:
(())()
()(())
(()())
Sample Input
6 2
300 150
Sample Output
3

1

题目大意:n个括号,深度为d的种类有多种,

分成两部分,dp[i][j]表示i对,深度最多为j的有多少种,把括号分为两部分,一部分深度不超过j,一部分不超过j-1

转移方程dp[i][j]=dp[k][j-1]*dp[i-k-1][j]+dp[i][j];

深度的话就减一下就好了dp[n/2][m]-dp[n/2][m-1];

ac代码

16453524 10157 Expressions Accepted C++ 4.216 2015-11-18 07:47:56
#include<stdio.h>
#include<string.h>
#include<iostream>
#include<algorithm>
#define LL long long
using namespace std;
const int M=155;
const int N=105;
struct bign {
    int len, sex;
    int s[N];

    bign() {
        this -> len = 1;
        this -> sex = 0;
        memset(s, 0, sizeof(s));
    }

    bign operator = (const char *number) {
        int begin = 0;
        len = 0;
        sex = 1;
        if (number[begin] == '-') {
            sex = -1;
            begin++;
        }
        else if (number[begin] == '+')
            begin++;

        for (int j = begin; number[j]; j++)
            s[len++] = number[j] - '0';
    }

    bign operator = (int number) {
        char string[N];
        sprintf(string, "%d", number);
        *this = string;
        return *this;
    }

    bign (int number) {*this = number;}
    bign (const char* number) {*this = number;}

    bign change(bign cur) {
        bign now;
        now = cur;
        for (int i = 0; i < cur.len; i++)
            now.s[i] = cur.s[cur.len - i - 1];
        return now;
    }

    void delZore() {    // 删除前导0.
        bign now = change(*this);
        while (now.s[now.len - 1] == 0 && now.len > 1) {
            now.len--;
        }
        *this = change(now);
    }

    void put() {    // 输出数值。
        delZore();
        if (sex < 0 && (len != 1 || s[0] != 0))
            cout << "-";
        for (int i = 0; i < len; i++)
            cout << s[i];
    }

    bign operator + (const bign &cur){
        bign sum, a, b;
        sum.len = 0;
        a = a.change(*this);
        b = b.change(cur);

        for (int i = 0, g = 0; g || i < a.len || i < b.len; i++){
            int x = g;
            if (i < a.len) x += a.s[i];
            if (i < b.len) x += b.s[i];
            sum.s[sum.len++] = x % 10;
            g = x / 10;
        }
        return sum.change(sum);
    }

    bign operator * (const bign &cur){
        bign sum, a, b;
        sum.len = 0;
        a = a.change(*this);
        b = b.change(cur);

        for (int i = 0; i < a.len; i++){
            int g = 0;

            for (int j = 0; j < b.len; j++){
                int x = a.s[i] * b.s[j] + g + sum.s[i + j];
                sum.s[i + j] = x % 10;
                g = x / 10;
            }
            sum.len = i + b.len;

            while (g){
                sum.s[sum.len++] = g % 10;
                g = g / 10;
            }
        }
        return sum.change(sum);
    }

    bign operator - (const bign &cur) {
        bign sum, a, b;
        sum.len = len;
        a = a.change(*this);
        b = b.change(cur);

        for (int i = 0; i < b.len; i++) {
            sum.s[i] = a.s[i] - b.s[i] + sum.s[i];
            if (sum.s[i] < 0) {
                sum.s[i] += 10;
                sum.s[i + 1]--;
            }
        }
        for (int i = b.len; i < a.len; i++) {
            sum.s[i] += a.s[i];
            if (sum.s[i] < 0) {
                sum.s[i] += 10;
                sum.s[i + 1]--;
            }
        }
        return sum.change(sum);
    }
};
bign dp[M][M];
void DP()
{
    int i,j,k;
    for(i=0;i<=150;i++)
        dp[0][i]=1;
    for(i=1;i<=150;i++)
    {
        for(j=1;j<=150;j++)
        {
            for(k=0;k<i;k++)
            {
                dp[i][j]=dp[k][j-1]*dp[i-k-1][j]+dp[i][j];
            }
        }
    }
}
int main()
{
    int n,m;
    DP();
    while(scanf("%d%d",&n,&m)!=EOF)
    {
        bign sum=dp[n/2][m]-dp[n/2][m-1];
        sum.put();
        printf("\n");
    }
}


0
0

查看评论
* 以上用户言论只代表其个人观点,不代表CSDN网站的观点或立场
    其实
    个人资料
    • 访问:384589次
    • 积分:14019
    • 等级:
    • 排名:第881名
    • 原创:1054篇
    • 转载:32篇
    • 译文:0篇
    • 评论:35条