Codeforces Round #505 D. Recovering BST 区间DP

版权声明:布呗之路的守望者 https://blog.csdn.net/hypHuangYanPing/article/details/82117971
/**
链接:https://codeforces.com/contest/1025/problem/D
题意:给出n个数 将这些数构造成一颗二叉树 问是否存在这样的二叉树使得树上任意相邻两点的gcd>1;
分析:pre[i][j] 表示点i j是否能构成一条边 pre[i][j]=gcd(a[i],a[j])>1;
fl[i][j]:j向左扩展是否能连通i;
fr[i][j]::i向右扩展是否能连通j;
可选择枚举区间长度进行暴力 看所在区间的每个点是否能够连通 一步一步进行前后状态的转移
转移后若能得到当len==n时,fl[i][j] 或者fr[i][j]存在即可; 
*/

#include<bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn=705;
int n,a[maxn],pre[maxn][maxn],fl[maxn][maxn],fr[maxn][maxn];
int gcd(int x,int y){return y==0?x:gcd(y,x%y);}

int main(){
	scanf("%d",&n);
	for(int i=1;i<=n;i++) scanf("%d",&a[i]);
	for(int i=1;i<=n;i++)
        for(int j=i+1;j<=n;j++)
        pre[i][j]=(gcd(a[i],a[j])>1),pre[j][i]=pre[i][j];

	for(int i=1;i<=n;i++) fl[i][i]=fr[i][i]=1;
	for(int len=1;len<=n;len++){
		for(int l=1;l<=n-len+1;l++){
			int r=l+len-1;
			for(int k=l;k<=r;k++){
				if((!fl[k][l])||(!fr[k][r]))	continue;
				if(len==n) { puts("Yes");return 0;}
				if(pre[l-1][k])	fr[l-1][r]=1;
				if(pre[k][r+1])	fl[r+1][l]=1;
			}
		}
	}
	puts("No");
	return 0;
}

猜你喜欢

转载自blog.csdn.net/hypHuangYanPing/article/details/82117971