题目:戳这里
题意:给一个不下降序列,有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 }