标签:塔顶 ll probe 305 int 序列 T208925 dp
【题意】
给定一个01序列,求有多少个互不相同的树的欧拉序为这个序列(每次进入和回溯都记录在序列中)
【分析】
显然这是一个树的计数问题,24分的部分分就是给暴力dfs统计的
考虑对于$n\leq300$的情况该怎么处理
计数问题比较常见的方法有数学推式子,dp类型,容斥类......
这道题目的数据范围也在提示我们向dp靠拢
我们考虑设计状态f[i][j]表示序列i-j部分的方案数
我们发现这个问题有可以区间合并的性质,即i-k-1形成的树形结构和k-j的树结构可以通过拼凑来对i-j产生贡献
那么我们考虑如何转移
f[l][r] 可以由f[l][k]和f[k+1][r]转移而来 表示先走完l+1-k-1是l的子树的一部分,然后从k-r走l的另一棵子树最后回来
显然r-l一定要是偶数才可以,且l和r是一个节点
【分析】
#include<bits/stdc++.h> using namespace std; typedef long long ll; const ll mod=1e9; ll f[305][305]; char s[305]; int n; int main() { freopen("probe.in","r",stdin); freopen("probe.out","w",stdout); scanf("%s",s+1); n=strlen(s+1); for(int i=1;i<=n;i++) f[i][i]=1; for(int len=3;len<=n;len+=2) for(int l=1;l+len-1<=n;l++) { int r=l+len-1; if(s[l]!=s[r]) continue; f[l][r]=f[l+1][r-1]; for(int k=l+2;k<=r-2;k++) if(s[l]==s[k]) f[l][r]=(f[l][r]+f[l+1][k-1]*f[k][r]%mod)%mod; } printf("%lld\n",f[1][n]); return 0; }
标签:塔顶,ll,probe,305,int,序列,T208925,dp 来源: https://www.cnblogs.com/andylnx/p/15521793.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。