Codeforces-1025D:Recovering BST(区间DP)

版权声明:http://blog.csdn.net/Mitsuha_。 https://blog.csdn.net/Mitsuha_/article/details/81866184

D. Recovering BST
time limit per test1 second
memory limit per test256 megabytes
inputstandard input
outputstandard output
Dima the hamster enjoys nibbling different things: cages, sticks, bad problemsetters and even trees!

Recently he found a binary search tree and instinctively nibbled all of its edges, hence messing up the vertices. Dima knows that if Andrew, who has been thoroughly assembling the tree for a long time, comes home and sees his creation demolished, he’ll get extremely upset.

To not let that happen, Dima has to recover the binary search tree. Luckily, he noticed that any two vertices connected by a direct edge had their greatest common divisor value exceed 1.

Help Dima construct such a binary search tree or determine that it’s impossible. The definition and properties of a binary search tree can be found here.

Input
The first line contains the number of vertices n ( 2 n 700 ) .

The second line features n distinct integers a i ( 2 a i 10 9 ) — the values of vertices in ascending order.

Output
If it is possible to reassemble the binary search tree, such that the greatest common divisor of any two vertices connected by the edge is greater than 1, print “Yes” (quotes for clarity).

Otherwise, print “No” (quotes for clarity).

Examples
input
6
3 6 9 18 36 108
output
Yes
input
2
7 17
output
No
input
9
4 8 10 12 15 18 33 44 81
output
Yes

思路:因为a数组是已经排好序的。所以我们可以用 d [ L ] [ R ] 表示区间 [ L , R ] 内的数是否能构成满足题意的二叉树。

所以对于每个区间 [ L , R ] 枚举其根节点 i ,于是这个 i 把这个区间分成了2个子区间 [ L , i 1 ] [ i + 1 , R ] 即分别为 i 的左儿子和右儿子。

但是这样存在一个问题,如何满足题目要求的任意连边的2点的gcd大于1呢?

如果把数组多开一维 d [ L ] [ R ] [ r o o t ] 表示区间 [ L , R ] 在以 r o o t 为根时,是否能满足条件,会超内存。

仔细观察课发现对于一个区间 [ L , R ] ,它的根节点只可能是 a [ L 1 ] a [ R + 1 ]
于是可以用 d [ L ] [ R ] [ 0 / 1 ] 表示区间 [ L , R ] 在以 a [ L 1 ] / a [ R + 1 ] 为根时,是否满足条件。

#include<bits/stdc++.h>
using namespace std;
const int MOD=998244353;
const int MAX=1e6+10;
const double PI=acos(-1.0);
typedef long long ll;
int gcd(int x,int y){return y==0?x:gcd(y,x%y);}
int d[710][710][2];
int a[710];
int dfs(int L,int R,int x)
{
    if(L>R)return 1;
    if(d[L][R][x]!=-1)return d[L][R][x];
    int y=(x==0?a[L-1]:a[R+1]);
    for(int i=L;i<=R;i++)
    {
        if(gcd(y,a[i])==1)continue;
        if(dfs(L,i-1,1)&&dfs(i+1,R,0))return d[L][R][x]=1;
    }
    return d[L][R][x]=0;
}
int main()
{
    int n;
    cin>>n;
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    memset(d,-1,sizeof d);
    for(int i=1;i<=n;i++)
    {
        if(dfs(1,i-1,1)&&dfs(i+1,n,0))
        {
            puts("Yes");
            return 0;
        }
    }
    puts("No");
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Mitsuha_/article/details/81866184