M4--C-The Crisis of Space Dog

topic

Insert picture description here
Insert picture description here

Insert picture description here
Insert picture description here

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;
}

Guess you like

Origin blog.csdn.net/alicemh/article/details/106604486
Dog