zoukankan      html  css  js  c++  java
  • [Gym 101334E]Exploring Pyramids(区间dp)

    题意:给定一个先序遍历序列,问符合条件的树的种类数

    解题关键:枚举分割点进行dp,若符合条件一定为回文序列,可分治做,采用记忆化搜索的方法。

    转移方程:$dp[i][j] = sum {dp[i + 1][k - 1]*dp[k][j]} $ 令$dp[i][j]$表示i到j里数量

    1、记忆化搜索

    #include <bits/stdc++.h>
    using namespace std;
    typedef long long ll;
    const int mod=1e9;  
    ll dp[305][305];  
    char a[305];  
      
    ll dfs(int l,int r){
        if(dp[l][r]!=-1)return dp[l][r];
        if(l==r) return dp[l][r]=1;
        if(a[l]!=a[r]) return 0;
        dp[l][r]=0;
        for(int i=l+2;i<=r;i+=2){
            if(a[i]==a[l]){
                dp[l][r]+=dfs(l+1,i-1)*dfs(i,r);//一定注意dp的顺序 
                dp[l][r]%=mod;
            }
        }
        return dp[l][r];
    }
    
    int main(){ 
        freopen("exploring.in", "r", stdin);  
        freopen("exploring.out", "w", stdout);
        while(~scanf("%s", a)){
            memset(dp,-1,sizeof dp);
            int len=strlen(a); 
            printf("%lld
    ", dfs(0,len-1)%mod);
            }
        return 0; 
    }

    2、区间dp

    #include<bits/stdc++.h> 
    #define mod 1000000000
    using namespace std;
    typedef long long ll;
    string a;
    ll dp[305][305],len;
    int main(){
        freopen("exploring.in", "r", stdin);  
        freopen("exploring.out", "w", stdout);
        while(cin>>a){
            memset(dp,0,sizeof dp);
            len=a.size();
            if(len%2==0){
                cout<<0<<endl;
                continue;
            }
            for(int i=0;i<len;i++)    dp[i][i]=1;
            for(int i=2;i<len;i+=2){
                for(int l=0,r;l+i<len;l++){
                    r=l+i;
                    if(a[l]==a[r]){
                        for(int k=l+1;k<=r;k++)
                            if(a[k]==a[l])
                                dp[l][r]=(dp[l][r]+dp[l+1][k-1]*dp[k][r])%mod;
                    }
                }
            }
            cout<<dp[0][len-1]<<endl;
        }
        return 0;
    }
  • 相关阅读:
    什么是Java
    程序有问题解决方法
    面向对象三大特征
    实例变量和局部变量
    内存管理
    常见面试题(更新中)
    多态
    设计规则
    内部类
    编程英语
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7800589.html
Copyright © 2011-2022 走看看