• [CF1025D] Recovering BST


    [CF1025D] Recovering BST - 区间dp

    Description

    给定一棵二叉搜索(n le 700) 的所有点权,构造二叉树满足任意两个直接相邻的点的权值的 GCD 不是 1

    Solution

    这种关于二叉搜索树中序遍历的 DP 问题,设状态时忽略根而考虑区间,因为这个区间作为一个子树,它的父亲一定是区间左端点的左边的点或者区间右端点的右边的点

    (f[i][j]) 表示以 ([i,j-1]) 作为 j 的左孩子是否合法

    (g[i][j]) 表示以 ([i+1,j]) 作为 i 的右孩子是否合法

    转移时,考虑一个区间 ([l,r]),枚举它的根 (k),需要满足 (f[i][k]) 并且 (g[k][j])

    如果此时 (k)(l-1) 相连是合法的,那么就可以转移到 ([l-1,r])

    如果此时 (k)(r+1) 相连是合法的,那么就可以转移到 ([l,r+1])

    总之,设状态时设的是“半棵子树”的合法性,转移时首先考虑一个区间可能有哪些根,然后分别考虑这些点为根时,向外的转移情况

    #include <bits/stdc++.h>
    using namespace std;
    
    #define int long long
    
    const int N = 705;
    
    // 设 $f[i][j]$ 表示以 $[i,j-1]$ 作为 j 的左孩子是否合法
    // 设 $g[i][j]$ 表示以 $[i+1,j]$ 作为 i 的右孩子是否合法
    
    int f[N][N], g[N][N], a[N], n, x[N][N];
    
    signed main()
    {
        ios::sync_with_stdio(false);
    
        cin >> n;
        for (int i = 1; i <= n; i++)
            cin >> a[i];
    
        for (int i = 1; i <= n; i++)
            f[i][i] = g[i][i] = 1;
    
        for (int i = 1; i <= n; i++)
            for (int j = 1; j <= n; j++)
                if (__gcd(a[i], a[j]) > 1)
                    x[i][j] = 1;
    
        for (int i = n; i >= 1; i--)
        {
            for (int j = i; j <= n; j++)
            {
                int l = i, r = j;
                for (int k = l; k <= r; k++)
                {
                    if (f[i][k] && g[k][j])
                    {
                        if (l > 1 && x[l - 1][k])
                            g[l - 1][r] = 1;
                        if (r < n && x[r + 1][k])
                            f[l][r + 1] = 1;
                    }
                }
            }
        }
    
        for (int i = 1; i <= n; i++)
        {
            if (f[1][i] && g[i][n])
            {
                cout << "Yes" << endl;
                return 0;
            }
        }
        cout << "No" << endl;
    }
    
  • 相关阅读:
    kettle-学习参考
    spring retry 重试机制完整例子
    一个四五年的Java开发程序员,该准备哪些去面试?
    Java之io nio aio 的区别
    Java对象的存活判断
    Java+微信支付(下预购单+回调+退款+查询账单)
    Java +支付宝 +接入
    关于MQ 消息队列的通俗理解和 rabbitMQ 使用
    java 对接芝麻信用 -用芝麻私钥解密错误
    mysql 乐观判断 校验
  • 原文地址:https://www.cnblogs.com/mollnn/p/14354409.html
Copyright © 2020-2023  润新知