Solution -「CF 1025D」Recovering BST
Link.
给定序列 ,问是否存在一棵二叉搜索树,使得其中序遍历为 ,且相邻接的两点不互素。
。
显然的 DP: 表示区间 是否能构成以 为根的树。
一个重要的性质:若区间 构成二叉搜索树的一棵完整的子树,则其父亲是 或 。证明显然。
那么状态可以优化,令 表示区间 能否作为 的子树,转移:
当 或 ,认为逻辑与的最后一项为真即可。复杂度 。
#include <cstdio>
const int MAXN = 700;
int n, a[MAXN + 5];
bool f[MAXN + 5][MAXN + 5][2];
inline int gcd ( const int a, const int b ) { return b ? gcd ( b, a % b ) : a; }
inline bool toLeft ( const int fid, const int id ) {
return ! fid || ( a[fid] < a[id] && gcd ( a[fid], a[id] ) ^ 1 );
}
inline bool toRight ( const int fid, const int id ) {
return fid > n || ( a[id] < a[fid] && gcd ( a[id], a[fid] ) ^ 1 );
}
int main () {
scanf ( "%d", &n );
for ( int i = 1; i <= n; ++ i ) scanf ( "%d", &a[i] );
for ( int i = 1; i <= n; ++ i ) {
f[i][i][0] = toLeft ( i - 1, i );
f[i][i][1] = toRight ( i + 1, i );
f[i][i - 1][0] = f[i][i - 1][1] = true;
}
f[n + 1][n][0] = f[n + 1][n][1] = true;
for ( int len = 2; len <= n; ++ len ) {
for ( int i = 1, j; ( j = i + len - 1 ) <= n; ++ i ) {
bool &curl = f[i][j][0], &curr = f[i][j][1];
for ( int k = i; k <= j && ( ! curl || ! curr ); ++ k ) {
if ( f[i][k - 1][1] && f[k + 1][j][0] ) {
if ( toLeft ( i - 1, k ) ) curl = true;
if ( toRight ( j + 1, k ) ) curr = true;
}
}
}
}
puts ( f[1][n][0] || f[1][n][1] ? "Yes" : "No" );
return 0;
}
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现