topic
Ideas
Binary search tree
It is either an empty tree or a binary tree with the following properties: If its left subtree is not empty, the values of all nodes on the left subtree are less than the value of its root node; if its right subtree If the tree is not empty, the values of all nodes on the right subtree are greater than the value of its root node; its left and right subtrees are also binary sorted trees respectively.
Binary search tree is required to be binary and search tree
Problem solving
Using dynamic programming
f[i][j] to record i to j can it be constructed into such a binary search tree.
Record whether the gcd between every two numbers is greater than 1
l[i][j] represents a legal tree with j as the follow, i, j as the left subtree.
r[i][j] is a legal tree with i as the root and i and j as the right subtree.
Enumerate the length of the interval len, and the interval of the length in the array in turn, and enumerate the root node in the interval of this length, the transition condition is
l[q][root] && r[root][z], and at the same time in gcd2[ q-1][root], update r[q-1][z] and l[q][z+1] when gcd2[root][z + 1] is 1
Code
#include<iostream>
#include<string.h>
using namespace std;
int node[710];
int gcd(int a,int b){
return b == 0 ? a : gcd(b,a%b);}
bool f[710][710];
bool gcd2[710][710];
bool l[710][710],r[710][710];
int main()
{
int t;
cin>>t;
while(t--)
{
memset(f,0,sizeof(f));
memset(gcd2, 0, sizeof(gcd2));
memset(l, 0, sizeof(l));
memset(r, 0, sizeof(r));
int n;
cin>>n;
for(int i=1;i<=n;i++)
{
cin>>node[i];
l[i][i]=1;
r[i][i]=1;
}
for (int i = 1; i <= n; i++)
{
for (int j = 1; j <= n; j++)
{
if (i!=j && gcd(node[i], node[j]) > 1)
{
gcd2[i][j] = true;
}
}
}
for (int len = 0; len < n; len++)
{
for (int q = 1; q <= n-len; q++)
{
int z = q + len;
for (int root = q; root <= z; root++)
if (l[q][root] && r[root][z])
{
f[q][z] = 1;
if (gcd2[q - 1][root])
r[q - 1][z] = 1;
if (gcd2[root][z + 1])
l[q][z + 1] = 1;
}
}
}
if (f[1][n])
cout << "Yes" << endl;
else
cout << "No" << endl;
}
return 0;
}