Codefores 1025D Recovering BST

给定一个序列,问这个序列是否能够构成一个二叉搜索树,使得任一边连接的点的gcd大于1

区间dp

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;

const int maxn = 710;

int A[maxn];
bool G[maxn][maxn];
bool dp[maxn][maxn][2];

int gcd(int x, int y) {
    return y == 0 ? x : gcd(y, x % y);
}

int main() {
    int n; scanf("%d", &n);
    for (int i = 1; i <= n; i++) scanf("%d", &A[i]);
    for (int i = 1; i <= n; i++) for (int j = 1; j <= n; j++) {
        G[i][j] = (gcd(A[i], A[j]) > 1);
    }
    for (int len = 1; len <= n; len++) {
        for (int l = 1, r = l + len - 1; l + len - 1 <= n; l++, r++) {
            for (int m = l; m <= r; m++) {
                bool flag = true;
                if (l == m) {
                    flag &= true;
                } else {
                    flag &= dp[l][m - 1][0];
                }
                if (m == r) {
                    flag &= true;
                } else {
                    flag &= dp[m + 1][r][1];
                }
                if (flag) {
                    dp[l][r][1] |= G[m][l - 1];
                    dp[l][r][0] |= G[m][r + 1];
                }
            }
        }
    }

    for (int i = 1; i <= n; i++) {
        bool tag = true;
        if (i == 1) {
            tag &= true;
        } else {
            tag &= dp[1][i - 1][0];
        }
        if (i == n) {
            tag &= true;
        } else {
            tag &= dp[i + 1][n][1];
        }
        if (tag) {
            puts("Yes"); return 0;
        }
    }
    puts("No");
    return 0;
}

原文地址:https://www.cnblogs.com/xFANx/p/9513580.html

时间: 2024-10-21 07:36:41

Codefores 1025D Recovering BST的相关文章

codeforce #505D - Recovering BST 区间DP

1025D 题意: 有一个递增序列,问能不能构建出一颗每条边的端点值都不互质的二叉排序树. 思路: 区间DP,但是和常见的区间DP不一样, 这里dp[i][j]表示的是区间[i,j]能否以i为根建立一个小二叉排序树. 所以可以得到dp[i][j] 为true, 要求在[i+1,j]中有一个k,dp[k][i+1]和dp[k][j]都为true. 或者在i点的左边取件中,即要求在[j][i-1]中有一个k,dp[k][j]和dp[k][i-1]都为true. #include <algorithm

CF1025D Recovering BST

题意:给定序列,问能否将其构成一颗BST,使得所有gcd(x, fa[x]) > 1 解:看起来是区间DP但是普通的f[l][r]表示不了根,f[l][r][root]又是n4的会超时,怎么办? 看了题解发现惊为天人...... f_l[l][r]表示[l, r]能否构成l-1的右子树,f_r[l][r]表示[l, r]能否构成r+1的左子树. 然后我们就发现这个神奇的东西变成n3了...... 1 #include <cstdio> 2 3 const int N = 710; 4 5

Codeforces #505(div1+div2) D Recovering BST

题意:给你一个升序的数组,元素之间如果gcd不为1可以建边,让你判断是否可以建成一颗二叉搜索树. 解法:dp,首先建图,然后进行状态转移.因为如果点k左端与i相连,右端与k相连,则i和k可以相连,同时像左右两端拓展. 最后判断1和n是否相连即可. #include<cstdio> #include<algorithm> #include<cstring> #include<cmath> #include<vector> using namespa

Codeforces Round #505 (Div 1 + Div 2 Combined) Partial Solution

从这里开始 题目列表 瞎扯 Problem A Doggo Recoloring Problem B Weakened Common Divisor Problem C Plasticine zebra Problem D Recovering BST Problem E Colored Cubes Problem F Disjoint Triangles Problem G Company Acquisitions 瞎扯 打比赛,发现自己特别菜. 居然还苟且水上紫名 这个号不敢玩了.要努力学习

538. Convert BST to Greater Tree 二叉搜索树转换为更大树

Given a Binary Search Tree (BST), convert it to a Greater Tree such that every key of the original BST is changed to the original key plus sum of all keys greater than the original key in BST. Example: Input: The root of a Binary Search Tree like thi

验证给定序列是否是BST的preoder序列

from leetcode https://leetcode.com/problems/verify-preorder-sequence-in-binary-search-tree/ 比如序列 2, 1, 3 是如下图的BST的preorder 序列: 但是2, 3, 1就不会是一个preorder序列: 先复习一下BST,给定一个节点,其左子树的所有节点都小于该节点,右子树的所有节点都大于该节点:preorder序列是指在遍历该BST的时候,先记录根节点,再遍历左子树,然后遍历右子树:所以一个

笔试算法题(09):查找指定和值的两个数 &amp; 构造BST镜像树

出题:输入一个已经升序排序的数组和一个数字:要求在数组中查找两个数,这两个数的和正好等于输入的那个数字,输出任意一对数字就可以,要求时间复杂度是O(n): 分析:对于升序排序的数组{-i-j-k-m--},只有可能是i+m=j+k(j和k可能是同一个数),所以可以从两边往中间收缩而忽视其他交叉相加的情况: 解题: 1 void FindSumFactor(int *array, int length, int sum) { 2 int left=0, right=length-1; 3 whil

二叉查找树BST 模板

二叉查找树BST 就是二叉搜索树 二叉排序树. 就是满足 左儿子<父节点<右儿子 的一颗树,插入和查询复杂度最好情况都是logN的,写起来很简单. 根据BST的性质可以很好的解决这些东西 1.查询值 int Search(int k,int x) { if(x<a[k].key && a[k].l) Search(a[k].l,x); else if(x>a[k].key && a[k].r) Search(a[k].r,x); else retur

[LeetCode] Largest BST Subtree 最大的二分搜索子树

Given a binary tree, find the largest subtree which is a Binary Search Tree (BST), where largest means subtree with largest number of nodes in it. Note:A subtree must include all of its descendants.Here's an example: 10 / 5 15 / \ \ 1 8 7 The Largest