CF 1025D:Recovering BST
CF 1025D:Recovering BST
题目直达
题意:
BST树:
节点结构:每个节点包含一个键值(key)、一个左子树指针和一个右子树指针。
左子树:对于每个节点,左子树中的所有节点的键值都小于该节点的键值。
右子树:对于每个节点,右子树中的所有节点的键值都大于该节点的键值。
无重复键:通常情况下,BST 中不允许有重复的键值。
现在有 n 个数,问是否能形成一个BSt树,其中每相邻的两个点不互质
思路(类比归并排序):
我们定义:dp[i][j][0/1] 表示区间 l - r 以(l-1)/(r+1)为根节点是否符合条件
我们枚举每一个点假定为根,再在被分开的两个区间内继续枚举子根,直到找到符合条件或者已经枚举完每一个点
具体见代码如下
#include<iostream>
#include<algorithm>
#include <cstring>
using namespace std;
int a[710];
bool g[710][710];
int dp[710][710][2];
int dfs(int l, int r, int k){
if(l > r) return 1;
if(dp[l][r][k] != -1) return dp[l][r][k];
int x = k?r+1:l-1;
for(int i = l;i <= r;i ++){
if(!g[x][i]) continue;
if(dfs(l, i - 1, 1) && dfs(i + 1, r, 0)) return dp[l][r][k] = 1;
}
return dp[l][r][k] = 0;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
memset(dp, -1, sizeof(dp));
int n;
cin >> n;
for(int i = 1;i <= n;i ++) cin >> a[i];
// 预处理存下互质的对(这里不存也是可以过的,n<=700)
for(int i = 1;i <= n;i ++)
for (int j = 1; j < i; j++){
if (__gcd(a[i], a[j]) > 1){
g[i][j] = true;
g[j][i] = true;
}
}
for(int i = 1;i <= n;i ++){
//继续递归子区间,找符合条件的根
if(dfs(1, i - 1, 1) && dfs(i + 1, n, 0)){
cout << "Yes";
return 0;
}
}
cout << "No";
return 0;
}

浙公网安备 33010602011771号