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;
    }
  • 相关阅读:
    input回车问题
    Jquery-无法有效获取当前窗口高度
    微信JSSDK支付接口-安卓机无法正常调起接口
    Kafka 1.1新功能:数据的路径间迁移
    KSQL和Flink SQL的比较
    关于Kafka监控方案的讨论
    关于Kafka配额的讨论(2)
    关于Kafka配额的讨论(1)
    【译】Flink + Kafka 0.11端到端精确一次处理语义的实现
    Kafka元数据缓存(metadata cache)
  • 原文地址:https://www.cnblogs.com/elpsycongroo/p/7800589.html
Copyright © 2011-2022 走看看