【非原创】codeforces 1025D - Recovering BST【区间dp+二叉搜索树】

题目:戳这里

题意:给一个不下降序列,有n个数。问能否构造一个二叉搜索树,满足父亲和儿子之间的gcd>1.

解题思路:其实这题就是构造个二叉搜索树,只不过多了个条件。主要得了解二叉搜索树的性质,比如一段区间[l,r],这段区间要么是[l-1]的右子树,要么是[r+1]的左子树。(二叉树中左子树都比根小,右子树都比根大

根据这个性质,用dfs构造二叉搜索树,构造的时候判断儿子和父亲的gcd是否大于1即可。

 

看到一个博客代码写的很漂亮,学习一下。

 1 #include<bits/stdc++.h>
 2 using namespace std;
 3 typedef long long ll;
 4 const int inf = 0x3f3f3f3f;
 5 const int maxn = 700 + 10;
 6 #define lowbit(x) x&-x
 7 int gcd(int a, int b) {
 8     return b?gcd(b,a%b):a;
 9 }
10 int dp[maxn][maxn][2];
11 int a[maxn];
12 bool dfs(int l, int r, int x) {
13     if(l > r) return 1;
14     if(dp[l][r][x] != -1) return dp[l][r][x];
15     int y=(x?a[r+1]:a[l-1]);
16     for(int i = l; i <= r; ++i) {
17         if(gcd(y, a[i]) == 1) continue;
18         if(dfs(l, i-1, 1) && dfs(i+1,r,0)) {
19             return dp[l][r][x] = 1;
20 
21         }
22     }
23     return dp[l][r][x] = 0;
24 
25 }
26 int main() {
27     int n;
28     scanf("%d", &n);
29     for(int i = 1; i <= n; ++i) {
30         scanf("%d", &a[i]);
31     }
32     memset(dp, -1, sizeof(dp));
33     for(int i = 1; i <= n; ++i) {
34         if(dfs(1, i - 1, 1) && dfs(i + 1, n, 0)) {
35             puts("Yes");
36             return 0;
37         }
38     }
39     puts("No");
40     return 0;
41 }
View Code

 

posted @ 2018-11-08 16:32  euzmin  阅读(136)  评论(0编辑  收藏  举报