zoukankan      html  css  js  c++  java
  • Codeforces Round #554 (Div. 2) D 贪心 + 记忆化搜索

    https://codeforces.com/contest/1152/problem/D

    题意

    给你一个n代表合法括号序列的长度一半,一颗有所有合法括号序列构成的字典树上,选择最大的边集,边集的边没有公共点,问边集大小

    题解

    • 对于一颗字典树,从低向上贪心,最底层的边全拿,定义好状态,记忆化搜索计数
    • 定义dp[i][j]为左括号数量为i,右括号数量为j的最大边集
      • (i<n),(dp[i][j]->dfs(i+1,j))
      • (j<i),(dp[i][j]->dfs(i,j+1))
    • 注意一下,相邻两层不能连续选边

    代码

    #include<bits/stdc++.h>
    #define ll long long
    #define P 1000000007
    #define pii pair<ll,int>
    #define mk make_pair
    #define ft first
    #define se second
    using namespace std;
    pii dp[1005][1005];
    int n;
    
    pii dfs(int i,int j){
        if(i==n&&j==n)return mk(0,0);
        pii &ans=dp[i][j];
        if(ans.ft>=0)return ans;
        ans=mk(0,1);
        if(i<n){
            pii tp=dfs(i+1,j);
            ans.ft+=tp.ft;ans.ft%=P;
            ans.se&=tp.se;
        }
        if(j<i){
            pii tp=dfs(i,j+1);
            ans.ft+=tp.ft;ans.ft%=P;
            ans.se&=tp.se;
        }
        if(ans.se==0){ans.ft++;ans.ft%=P;}
        ans.se^=1;
        return ans;
    }
        
    int main(){
        cin>>n;
        for(int i=0;i<=n;i++)for(int j=0;j<=n;j++)dp[i][j]=mk(-1,-1);
        cout<<dfs(1,0).ft;
    }
    
  • 相关阅读:
    反射和内置方法重写
    封装
    接口与抽象类 、多态
    面向对象--继承和组合
    python对象
    模块导入
    python序列化模块
    time random sys os 模块
    python re模块和collections
    python各种推导式
  • 原文地址:https://www.cnblogs.com/VIrtu0s0/p/10812834.html
Copyright © 2011-2022 走看看