zoukankan      html  css  js  c++  java
  • CF D. Recovering BST (区间DP)

    题意:给你n个节点,每个节点有一个权值,两个点可以连边当且仅当这两个点的gcd>1,问你这n个点能否构成一个二叉搜索树(每个节点最多有两个儿子,且左儿子小于右儿子),输入为递增顺序。

    分析:

    若以第K个节点,用L[i][k] ,表示是否可以延伸到i点,R[k][j]表示是否可以延伸到J点,那区间【L,R]怎样才是合法的呢?很显然只有L[i][k] && R[k][j] ==1,时这个区间才是合法的,那只要在【1,n】,这个区间里找到存在点K ,那就是YES ,否则NO;

    #include<stdio.h>
    const int maxn = 701;
    int gcd(int a , int b)
    {
        if(b==0)
        return a;
        return gcd(b,a%b);
    }
    int a[maxn],L[maxn][maxn],R[maxn][maxn],val[maxn][maxn];
    int main( )
    {
        int n ;
        scanf("%d",&n) ;
        for(int i=1 ; i<=n ; i++)
        {
             scanf("%d",&a[i]) ;
             L[i][i]=R[i][i]=1;
        }
    
    
        for(int i=1 ; i<n ; i++)
            for(int j=i+1 ; j<=n ; j++)
        {
            if(gcd(a[i],a[j])>1)
            {
                val[i][j]=val[j][i]=1;
            }
            else
            {
                val[i][j]=val[j][i]=0;
            }
        }
        for(int l=n ; l>=1 ;  l--)
        {
            for(int r=l ; r<=n ; r++)
            {
                for(int k=l ; k<=r ; k++)
                {
                    if(L[l][k] && R[k][r])
                    {
                        if(l==1&&r==n)
                        {
                            printf("Yes
    ");
                            return 0;
                        }
                        if(val[k][l-1]) R[l-1][r]=1;
                        if(val[k][r+1]) L[l][r+1]=1;
                    }
                }
            }
        }
        puts("No");
        return 0 ;
    }
    View Code
  • 相关阅读:
    学习笔记4
    学习笔记2
    学习笔记1
    树莓派与Arduino串口通信
    团队大作业第三周周报
    团队大作业第二周周报
    团队大作业第一周周报
    RTCSD_第三次作业
    RTCSD_第二次作业
    RTCSD_第一次作业
  • 原文地址:https://www.cnblogs.com/shuaihui520/p/9552563.html
Copyright © 2011-2022 走看看