这题帮我复习了一下BST的中序遍历。。
因为给定的数组是递增的,那么BST的中序遍历一定是1 2 3 4 5 6 7 8 9 ... n
即[l,r]为左子树,那么根节点就是r+1,反之根节点就是l-1
那么我们只要枚举每个区间[l,r],再枚举[l,r]的根k,然后看l-1,r+1是否可以作为k的父亲。以此来扩展dp状态
L[l.r] | R[l,r]表示区间[l,r]的根是 l | r 是否可行
那么显然就是一个三重区间dp
#include<bits/stdc++.h> using namespace std; #define maxn 705 int n,a[maxn],g[maxn][maxn],L[maxn][maxn],R[maxn][maxn]; int main(){ cin>>n;for(int i=1;i<=n;i++)cin>>a[i]; for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) g[i][j]=__gcd(a[i],a[j]); for(int i=1;i<=n;i++)L[i][i]=R[i][i]=1; for(int len=1;len<=n;len++) for(int l=1;l+len-1<=n;l++){ int r=l+len-1; for(int k=l;k<=r;k++)//以k作为根节点 if(L[l][k] && R[k][r]){ if(l==1 && r==n){ puts("Yes"); return 0; } if(g[l-1][k]>1)R[l-1][r]=1;//[l,r]作为l-1的右儿子 if(g[k][r+1]>1)L[l][r+1]=1;//[l,r]作为r+1的左儿子- } } puts("No"); }