zoukankan      html  css  js  c++  java
  • 《算法竞赛进阶指南》0x53区间DP Acwing284金字塔

    题目链接:https://www.acwing.com/problem/content/286/

    给定一棵树的DFS序,求这棵树可能的形状有多少种?

    由于dfs序中,每条边都访问两遍,从根节点进入只有一次,所以在有n个结点的树的DFS序的长度是2*n-1。根据区间DP,可以先构造这棵树的最右侧的子树,枚举进入的字符串,算出最右侧子树能够多少种构造方法,与左边一段的序列构造的树的数量相乘就得到了一次决策的数量,枚举右子树的进入点,进行决策的累加就得到了最终区间的决策数量。

    注意:子树的dfs序的长度一定是奇数,所以在枚举左边序列组成的树的时候需要其长度是奇数。k=l代表的是左侧组成根节点,只有一个点,没有其余子树。

    代码:

    #include<iostream>
    #include<cstdio>
    #include<string>
    using namespace std;
    const int maxn = 310;
    const int mod=1e9;
    int f[maxn][maxn];
    string s;
    int main(){
        cin>>s;
        int n=s.length();
        if(n%2==0)puts("0");
        else{
            for(int len=1;len<=n;len++)
                for(int l=0;l+len-1<n;l++)
                {
                    int r=l+len-1;
                    if(len==1)f[l][r]=1;
                    if(s[l]==s[r]){
                        for(int k=l;k<r;k+=2){//保证子树的dfs序是奇数 
                            if(s[k]==s[r]){
                                f[l][r]=(f[l][r]+(long long)f[l][k]*f[k+1][r-1])%mod;
                            }
                        }
                    }
                }
                
            cout<<f[0][n-1]<<endl;
        }
    }
  • 相关阅读:
    多线程(一) NSThread
    Swift 烧脑体操(一)
    Swift 烧脑体操(二)
    UINavigationController使用的注意事项
    更多请查看我的文章
    本地通知
    网络编程(二)NSURLSessionConfiguration
    A
    51Nod 1116 K进制下的大数(暴力枚举)
    51Nod 1065 最小正子段和
  • 原文地址:https://www.cnblogs.com/randy-lo/p/13404448.html
Copyright © 2011-2022 走看看