zoukankan      html  css  js  c++  java
  • 【非原创】codeforces 1025D

    题目:戳这里

    题意:给一个不下降序列,有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
  • 相关阅读:
    1.33 (累积互素数)
    1.33 (过滤累积和 求区间内所有素数之和)
    1.32 (更高层次的抽象! 乘法与加法本来就是一回事)
    1.31 (另一种求圆周率的算法)
    1.30 (递归的sum变迭代)
    习题1.29 (积分方法的优化---simpson规则)
    1.3.1 (对过程的抽象)
    SICP习题 1.23(素数查找的去偶数优化)
    SICP习题 1.22(素数)
    pom.xml
  • 原文地址:https://www.cnblogs.com/zmin/p/9929912.html
Copyright © 2011-2022 走看看