zoukankan      html  css  js  c++  java
  • CF1152 D. Neko and Aki's Prank

    题目传送门:https://codeforces.com/problemset/problem/1152/D

    题目大意:
    求一个长度为(2n)的所有合法括号序列构成的Trie树的最大匹配数(最大的边集使任意两条边无公共边)


    暴力画出一些(n)较小的Trie树后,我们可以发现一些规律:如果两点到根路径上左右括号数相同,则两点的子树形态一致

    基于这一点,我们直接Dfs+记忆化搜索即可

    /*program from Wolfycz*/
    #include<map>
    #include<cmath>
    #include<cstdio>
    #include<vector>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define Fi first
    #define Se second
    #define ll_inf 1e18
    #define MK make_pair
    #define sqr(x) ((x)*(x))
    #define pii pair<int,int>
    #define int_inf 0x7f7f7f7f
    using namespace std;
    typedef long long ll;
    typedef unsigned int ui;
    typedef unsigned long long ull;
    inline char gc(){
    	static char buf[1000000],*p1=buf,*p2=buf;
    	return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
    }
    template<typename T>inline T frd(T x){
    	int f=1; char ch=gc();
    	for (;ch<'0'||ch>'9';ch=gc())	if (ch=='-')    f=-1;
    	for (;ch>='0'&&ch<='9';ch=gc())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    template<typename T>inline T read(T x){
    	int f=1; char ch=getchar();
    	for (;ch<'0'||ch>'9';ch=getchar())	if (ch=='-')	f=-1;
    	for (;ch>='0'&&ch<='9';ch=getchar())	x=(x<<1)+(x<<3)+ch-'0';
    	return x*f;
    }
    inline void print(int x){
    	if (x<0)	putchar('-'),x=-x;
    	if (x>9)	print(x/10);
    	putchar(x%10+'0');
    }
    const int N=1e3,P=1e9+7;
    int F[N+10][N+10][2],n;
    bool vis[N+10][N+10];
    void Dfs(int L,int R){
    	if (vis[L-R][n-L])	return;
    	vis[L-R][n-L]=1;
    	if (L==R&&L==n)	return;
    	if (L<n&&L>R){
    		Dfs(L+1,R),Dfs(L,R+1);
    		int L0=F[L+1-R][n-L-1][0],L1=F[L+1-R][n-L-1][1];
    		int R0=F[L-R-1][n-L  ][0],R1=F[L-R-1][n-L  ][1];
    		F[L-R][n-L][1]=(L0+R0)%P;
    		F[L-R][n-L][0]=max(L0+R0,max(L1+R0+1,L0+R1+1))%P;
    		return;
    	}
    	if (L<n){
    		Dfs(L+1,R);
    		F[L-R][n-L][1]=F[L+1-R][n-L-1][0]%P;
    		F[L-R][n-L][0]=max(F[L+1-R][n-L-1][0],F[L+1-R][n-L-1][1]+1)%P;
    	}
    	if (L>R){
    		Dfs(L,R+1);
    		F[L-R][n-L][1]=F[L-R-1][n-L][0]%P;
    		F[L-R][n-L][0]=max(F[L-R-1][n-L][0],F[L-R-1][n-L][1]+1)%P;
    	}
    }
    int main(){
    //	freopen(".in","r",stdin);
    //	freopen(".out","w",stdout);
    	n=read(0),Dfs(0,0);
    	printf("%d
    ",F[0][n][0]);
    	return 0;
    }
    
    作者:Wolfycz
    本文版权归作者和博客园共有,欢迎转载,但必须在文章开头注明原文出处,否则保留追究法律责任的权利
  • 相关阅读:
    菜单项向子页面传递参数
    Grid中添加链接,打开选项卡页面
    FineUI与百度地图简单示例 (转帖)
    AppBox中main树节点单击事件JS(还有叶子的节点的页面链接)
    FineUI中在一个页面中通过控件事件(JS)向父页面中添加Tab页
    如何使用button在tab中新建打开一个链接页
    系统service
    官员详解官场对领导称谓讲究:叫大不叫小
    搞笑对话
    陆琪:男人生存的意义,就是赚钱养老婆
  • 原文地址:https://www.cnblogs.com/Wolfycz/p/14985363.html
Copyright © 2011-2022 走看看