虽然探索金字塔是极其老套的剧情,但是有一队探险家还是到了某金字塔脚下。

经过多年的研究,科学家对这座金字塔的内部结构已经有所了解。

首先,金字塔由若干房间组成,房间之间连有通道。

如果把房间看作节点,通道看作边的话,整个金字塔呈现一个有根树结构,节点的子树之间有序,金字塔有唯一的一个入口通向树根。

并且,每个房间的墙壁都涂有若干种颜色的一种。

探险队员打算进一步了解金字塔的结构,为此,他们使用了一种特殊设计的机器人。

这种机器人会从入口进入金字塔,之后对金字塔进行深度优先遍历。

机器人每进入一个房间(无论是第一次进入还是返回),都会记录这个房间的颜色。

最后,机器人会从入口退出金字塔。

显然,机器人会访问每个房间至少一次,并且穿越每条通道恰好两次(两个方向各一次), 然后,机器人会得到一个颜色序列。

但是,探险队员发现这个颜色序列并不能唯一确定金字塔的结构。

现在他们想请你帮助他们计算,对于一个给定的颜色序列,有多少种可能的结构会得到这个序列。

因为结果可能会非常大,你只需要输出答案对109 取模之后的值。

输入格式

输入仅一行,包含一个字符串 S,长度不超过 300,表示机器人得到的颜色序列。

输出格式

输出一个整数表示答案。

输入样例:

ABABABA

输出样例:

5

笔记来源于AcWing 284. 金字塔(《算法竞赛进阶指南》打卡活动) - AcWing

前置内容:

DFS序列:

如图,从点A出发到B,从点B出发到D,从点D出发返回B,从点B出发到E,从点E出发返回B······从点A出发到C,从点C出发到A。

从而得到DFS序列:ABDBEBFBACA

像不像一笔画。

知道流程后,我们可以发现一个规律,对于每一条边,我们都往返一次,共经历两次,对于n个顶点,我们有n - 1条边,而每一次经过边,都会搜索到一个点,所以DFS序列的长度为1(出发点) + 2 * (n - 1)= 2 * n - 1。

输入样例:

ABABABA

在样例中,DFS序列的长度为7,代入可得顶点的个数为4。

样例解释:

状态确立:

(这里R - 1是不合法的,因为最后一个点是n,R - 1不是一个DFS序列,最多是R - 2)

我们把一整条DFS序列拆出一个子链,那么这个子链是由红圈中的部分贡献的DFS序列。

但这些状态不是全部都成立的,合理的状态需要满足一个条件

K,L,R代表的字母必须相同

状态转移:

我们把树分为两部分,总的方案数为两方的方案数之积。

所以是f[L,R] = f[L,K] * f[K + 1,R]吗?

我们的方案数是左边的子树 * 右边的子树。

左边的子树是[L,R],右边的子树是[K + 1,R - 1]。

所以状态转移:

f[L,R] = f[L,K] * f[K + 1,R - 1]

我们最后再把所有不同种树的方案数相加,就得到最后的答案。

关于区间DP枚举方式的一点介绍:石子合并(算法竞赛进阶指南)_zyc_3的博客-CSDN博客

代码:

#include<bits/stdc++.h>
using namespace std;
const int mod = 1e9;
typedef long long ll;
ll f[305][305];
string st;
int n;int main()
{cin >> st;n = st.size();if(n % 2 == 0){cout << 0;}//判断是否有解else{for(int len = 1;len <= n;len += 2)//len的变化是因为每次子树的点数变化,一个点对应来回两次,对DFS序列贡献为2{for(int l = 0;l + len - 1 < n;l ++){int r = l + len - 1;if(len == 1)f[l][r] = 1;//初始化else if(st[l] == st[r]){for(int k = l;k < r;k += 2)//k += 2的理由同上 {if(st[k] == st[l])f[l][r] = (f[l][r] + f[l][k] * f[k + 1][r - 1]) % mod;//取不同的k值产生的f[l][r]要求总和}}}}cout << f[0][n - 1];}return 0;
}

金字塔(算法竞赛进阶指南)相关推荐

  1. 《算法竞赛进阶指南》打卡-基本算法-AcWing 93. 递归实现组合型枚举:递归与递推、dfs、状态压缩

    文章目录 题目解答 题目链接 题目解答 分析: 此题和笔者另一篇博文很像,只不过是限定了个数.<算法竞赛进阶指南>打卡-基本算法-AcWing 92. 递归实现指数型枚举:递推与递归.二进 ...

  2. 《算法竞赛进阶指南》数论篇

    <算法竞赛进阶指南>数论篇(1)-最大公约数,素数筛,欧拉函数,同余,欧拉定理,BSGS <算法竞赛进阶指南>数论篇(1)-最大公约数,素数筛,欧拉函数,同余,欧拉定理,BSG ...

  3. 《算法竞赛进阶指南(by 李煜东)》习题题解 集合

    又是笔者给自己挖的大坑. 这里是李煜东所著<算法竞赛进阶指南(by 李煜东)>的习题题解集合. 有任何错误请在对应文章下反馈或联系 nicest1919@163.com ,谢谢 qwq 从 ...

  4. CH5202 自然数拆分Lunatic版(算法竞赛进阶指南,完全背包)

    算法竞赛进阶指南,278页,完全背包 本题要点: 1.把完全背包的代码改改即可.常规的完全背包: 有n个物品,每个物品的体积是v[i], 价值是w[i], 求装到大小为m的大背包,能获得的最大价值(每 ...

  5. 中位数--《算法竞赛进阶指南》(货仓选址和七夕祭问题详解)

    中位数 今天又和大家见面了啦~ 依旧是 <算法竞赛进阶指南>的学习哦~ 中位数(Median)又称中值,统计学中的专有名词,是按顺序排列的一组数据中居于中间位置的数,代表一个样本.种群或概 ...

  6. AcWing 122. 糖果传递【贪心】【《算法竞赛进阶指南》,微软面试题 , HAOI2008】

    AcWing 122. 糖果传递 一.题目链接 二.题目分析 (一)算法标签 (二)解题思路 三.AC代码 四.其它题解 一.题目链接 AcWing 122. 糖果传递 进阶题目 AcWing 105 ...

  7. 算法竞赛进阶指南 骑士放置

    4: 最大独立集 :选出最多的点,使得选出的点之间没有边. 求最大独立集:选出最小的点可以破坏所有的边 <==>最小点覆盖 <==>最大匹配数. 假设最大匹配数为m,共有n个点 ...

  8. 算法竞赛进阶指南 萌新入门!

    算法竞赛进阶指南 文章目录 算法竞赛进阶指南 前言 一.介绍本书 二.如何阅读本书 三.总结 **笔记思路和结构 ** 算法竞赛进阶指南 这篇文章就简单的写一下吧! 前言 ​ 作为一个想要入坑的算法的 ...

  9. 算法竞赛进阶指南0x3A 博弈论之SG函数

    算法竞赛进阶指南0x3A 博弈论之SG函数

最新文章

  1. windows 报错 没有文件扩展.vbs的脚本引擎 解决方法
  2. PT60报错(在表 $ 中午关键字$的输入项目T555Z)
  3. Java 8 - 收集器Collectors_归约和汇总
  4. nodejs模块笔记
  5. Linux关闭开关机动画,centos7删除开机动画及修改启动菜单
  6. 御用导航提示页面_UI网站导航设计知识与五个知识案例
  7. SVN 本地文件锁/服务端文件锁清除步骤
  8. docker删除所有镜像和容器
  9. Windows Phone 8.1 多媒体(3):音乐
  10. Eclipse启动SpringCloud微服务集群的方法
  11. opencv-api drawKeyPoints
  12. win10树莓派改ip_在树莓派2上安装 Windows 10
  13. 专访 | 阿里前辈李智慧:如何培养架构思维,我把20年的架构经讲给你听
  14. 判断checkbox是否选中
  15. 模型压缩文献笔记_3:彩票假设及其家属。
  16. python手机版怎么用-如何用Python操控手机APP攻略!建议收藏!很全面
  17. 弘辽科技:如何拉免费流量的几个小妙招 。
  18. 31省市数字化转型路线图公布
  19. python实现两张图片拼接(身份证正反面图片拼接)
  20. Unity URP 曲面细分

热门文章

  1. 状态码401 和 403
  2. D3D11 立方体贴图(天空盒子)
  3. 计算机图形学专业 国内大学排名,虚拟现实应用技术专业大学排名 2020全国排行榜...
  4. 【电源专题】LDO基础——压降
  5. 一文搞懂晶振,晶振的作用和原理?
  6. 职工管理系统--基于C++多态
  7. 【求职】瓜子二手车 Java 方向面经
  8. 企业ERP管理软件有哪些?哪个好
  9. php 关键词挖掘,如何挖掘长尾关键词
  10. 如何让思路更清晰?simplemind for Mac思维导图来帮忙