hdu 5181 numbers——思路+区间DP
Posted narh
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hdu 5181 numbers——思路+区间DP相关的知识,希望对你有一定的参考价值。
题目:http://acm.hdu.edu.cn/showproblem.php?pid=5181
题解:https://www.cnblogs.com/Miracevin/p/10960717.html
原来卡特兰数的这个问题还能区间DP……
XO
#include<cstdio> #include<cstring> #include<algorithm> #define ll long long using namespace std; int rdn() int ret=0;bool fx=1;char ch=getchar(); while(ch>‘9‘||ch<‘0‘)if(ch==‘-‘)fx=0;ch=getchar(); while(ch>=‘0‘&&ch<=‘9‘)ret=ret*10+ch-‘0‘,ch=getchar(); return fx?ret:-ret; const int N=305,M=9e5+5,mod=1e9+7; int n,m,hd[N],xnt,to[M],nxt[M],b[N][N],f[N][N]; bool vis[N]; void init() memset(b,0,sizeof b); memset(f,0,sizeof f); xnt=0; memset(hd,0,sizeof hd); void add(int x,int y)to[++xnt]=y;nxt[xnt]=hd[x];hd[x]=xnt; void dfs(int cr) for(int i=hd[cr],v;i;i=nxt[i]) if(!vis[v=to[i]]) vis[v]=1; b[cr][v]=1; dfs(v); bool chk(int x1,int x2,int y1,int y2) if(x2<x1||y2<y1)return true; int tp=b[x2][y2]-b[x1-1][y2]-b[x2][y1-1]+b[x1-1][y1-1]; return !tp; void solve() for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) b[i][j]+=b[i][j-1]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) b[i][j]+=b[i-1][j]; for(int len=1;len<=n;len++) for(int i=1;i<=n;i++) int j=i+len-1; if(j>n)break; f[i][i-1]=f[j+1][j]=1; for(int k=i;k<=j;k++) if(chk(k,j,i,k-1)&&chk(k,k,k+1,j)) f[i][j]=(f[i][j]+(ll)f[i][k-1]*f[k+1][j])%mod; printf("%d\\n",f[1][n]); int main() int T=rdn(); while(T--) init(); n=rdn();m=rdn(); for(int i=1,u,v;i<=m;i++) u=rdn(),v=rdn(),add(u,v); for(int i=1;i<=n;i++) memset(vis,0,sizeof vis); dfs(i); bool fg=0; for(int i=1;i<=n&&(!fg);i++) for(int j=1;j<=i;j++) if(b[i][j]&&b[j][i])fg=1;break; if(fg)puts("0");continue; solve(); return 0;
以上是关于hdu 5181 numbers——思路+区间DP的主要内容,如果未能解决你的问题,请参考以下文章
HDU 3709 Balanced Number(数位dp)