\(\mathcal{Description}\)

  Link.

  给定 \(\{x_n\}\),对于满足 \(h_i\in[1,x_i]\) 的序列 \(\{h_n\}\),定义序列 \(\{p_n\}\) 满足:

\[p_i=\begin{cases}-1,&(\not\exist j<i)(h_j>h_i)\\\max_{j<i}\{j|h_j>h_i\},&\text{otherwise}\end{cases}
\]

  求所有可能出现的本质不同的 \(\{p_n\}\),对 \(10^9+7\) 取模。

  \(n\le100\)。

\(\mathcal{Solution}\)

  \(\{p_n\}\) 是一个下标对应关系,所以可以尝试着把关系化成图。正如 PKU 面试的那位老师所说:“图表示关系”。

  但 \(-1\) 明显很丑,令 \(a_0=+\infty\),那么对于 \(\{+\infty,3,1,2,5,4\}\),\(\{p\}\) 长成:

  多画几个目测一下,得到:

  1. 图是一棵以 \(0\) 为根的外向树(废话。
  2. 以 \(u\) 为根,大小为 \(s\) 的子树对应原序列的区间 \([u,u+s)\)。还可以用 DFN 描述:存在一种对于所有 \(i\),\(\operatorname{dfn}(i)=i\) 的 DFS 顺序。

  简证结论二:归纳证明,考虑 DFS 到 \(u\) 点后,是否一定存在一种方案,下一步 DFS 到 \(u+1\):

  • 若 \(h_u>h_{u+1}\),有直接连边,满足。
  • 若 \(h_u\le h_{u+1}\),则显然不存在 \(w>u+1\),使得 \(\langle u,w\rangle\in E\)。所以 DFS 返回过程中,除非满足上一条件走向 \(u+1\),否则不可能走向其他 \(>u\) 的结点。证毕。

  从计数的角度考虑,\(\{p\}\) 相等则代表这颗树的树形完全一样。所以可以对于每种树形,构造一个最可能存在的 \(\{h_n\}\)(所有值尽量小),只对这种 \(\{h_n\}\) 计数,就能实现不重不漏。归纳构造:

  • 对于叶子 \(u\),显然 \(h_u=1\) 最合适。
  • 对于非叶 \(u\),应满足 \(h_u\ge\max_{v\in son_u}\{h_v\}+1\);其次若再 \(u\) 的左侧有同父亲的兄弟 \(w\),则还要满足 \(h_u\ge h_w\),可以结合上图理解。所以直接钦定 \(h_u=\max\{h_w,\max_{v\in son_u}\{h_v\}+1\}\)。根据此构造方式,\(h_u\) 变小不会导致子树外 \(h\) 变大,所以这种构造能得到最可能存在的 \(\{h_n\}\)。注意上式也有一个重要的性质,\(\operatorname{arg}\max_{v\in son_u}\{h_v\}\) 为 \(u\) 最右侧的儿子。

  举个例子,对于上图,构造出的 \(\{h_n\}\) 为 \(\{3,2,1,1,2,1\}\)。

  走到现在都是凭感觉。


  由结论二,令 DP 状态 \(f(l,r,k)\) 表示区间 \([l,r]\) 构成一棵以 \(l\) 为根且 \(h_l=k\) 的树的方案数;同时令 \(g(l,r,k)\) 为其第三维前缀和,即区间 \([l,r]\) 构成一棵以 \(l\) 为根且 \(h_l\le k\) 的树的方案数。

  转移,首先枚举位置 \(p\) 把区间分为 \([l,p)\) 和 \([p,r]\),由于最右侧儿子最大,\(h_l=h_p+1\)。分 \(h_p\) 原来与 \([l,p)\) 中 \(h_l\) 的大小关系,有:

\[f(l,r,k)=\sum_{p=l+1}^rg(l,p-1,k)f(p,r,k-1)+[x_p\ge k-1]f(l,p-1,k)g(p,r,k-2)
\]

  前一项表示 \([p,r]\) 本身的 \(h_p\) 就为 \(k-1\);后一项则表示 \([p,r]\) 的 \(h_p\) 本身很小,但因为在左侧多了兄弟而被迫取到 \(k-1\)(所以要保证 \(x_p\ge k-1\),有能力取到 \(k-1\));\(f(l,p-1,k)f(p,r,k-1)\) 可能算重所以最后一项是 \(g(p,r,k-2)\)。

  最终,复杂度 \(\mathcal O(n^4)\)。(所以原题 \(x_i\le10^5\) 拿来干嘛 qwq……

\(\mathcal{Code}\)

/* Clearink */

#include <cstdio>

const int MAXN = 100, MAXX = 1e5, MOD = 1e9 + 7;
int n, a[MAXN + 5];
int f[MAXN + 5][MAXN + 5][MAXN + 5], g[MAXN + 5][MAXN + 5][MAXN + 5]; inline int mul ( long long a, const int b ) { return a * b % MOD; }
inline int& addeq ( int& a, const int b ) { return ( a += b ) < MOD ? a : a -= MOD; } int main () {
scanf ( "%d", &n ), a[1] = ++ n;
for ( int i = 2; i <= n; ++ i ) scanf ( "%d", &a[i] );
for ( int i = 1; i <= n; ++ i ) {
f[i][i][1] = 1;
for ( int k = 1; k <= n; ++ k ) g[i][i][k] = 1;
}
for ( int len = 2; len <= n; ++ len ) {
for ( int l = 1, r; ( r = l + len - 1 ) <= n; ++ l ) {
for ( int x = 2; x <= n && x <= a[l]; ++ x ) {
int& cur = f[l][r][x];
for ( int p = l + 1; p <= r; ++ p ) {
addeq ( cur, mul ( g[l][p - 1][x], f[p][r][x - 1] ) );
if ( a[p] >= x - 1 ) {
addeq ( cur, mul ( f[l][p - 1][x], g[p][r][x - 2] ) );
}
}
}
for ( int x = 1; x <= n; ++ x ) {
addeq ( g[l][r][x] = g[l][r][x - 1], f[l][r][x] );
}
}
}
printf ( "%d\n", g[1][n][n] );
return 0;
}

\(\mathcal{Details}\)

  随手画画图好习惯嗷!

最新文章

  1. hdu FatMouse&#39;s Speed 动态规划DP
  2. myeclipse下构建maven web项目
  3. Java之多线程开发时多条件Condition接口的使用
  4. 【网络编程】——linux socket demo
  5. 解决错误: java.lang.NoClassDefFoundError: antlr/RecognitionException
  6. Object-Oriented CSS
  7. [LeetCode]题解(python):107 Binary Tree Level Order Traversal II
  8. 一个好用的Log管理类
  9. zoj 2112 Dynamic Rankings
  10. java 防止sql注入的方法(非原创)
  11. 对web.config的ConnectionString加密
  12. Android系统对话框——自定义关闭
  13. 理解mysql执行多表联合查询
  14. jquery 学习(四) - 标签 添加/删除/修改
  15. django报错解决:view must be a callable or a list/tuple in the case of include().
  16. 分布式Session一致性解决方案有哪些?
  17. as3 arguments.callee与... (rest)
  18. 我的“MIT Challenge”
  19. Delphi 10 seattle 去掉自带的代码连接线
  20. python应用:爬虫框架Scrapy系统学习第一篇——xpath详解

热门文章

  1. 两张Number()函数图和Boolean()函数图
  2. HashMap原理及源码分析
  3. 《剑指offer》面试题40. 最小的k个数
  4. leetcode 645. 错误的集合
  5. 【解决了一个小问题】alpine镜像中,busybox的date命令获取昨天的日期
  6. was 9.0 install
  7. 如何加载本地下载下来的BERT模型,pytorch踩坑!!
  8. 密码学之PRP/PRF转换引理
  9. Git .gitignore 不起作用的解决办法
  10. 为什么内部类调用的外部变量必须是final修饰的?