题意:求图中内嵌二叉搜索树是否存在。
区间DP,dp[i][j]表示i到j的点是否可以构成一颗以i为根的二叉搜索树(i可以大于等于j)
根据二叉搜索树性质,dp[i][j] |= dp[k][j] & dp[k][i+1]…….
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#define maxn 705
using namespace std;
int n,val[maxn];
bool Map[maxn][maxn],dp[maxn][maxn];
inline int gcd(int a,int b){ return !b ? a : gcd(b , a % b); }
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++) scanf("%d",&val[i]);
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
if(gcd(val[i],val[j])>1)
Map[i][j] = Map[j][i] = 1;
for(int i=1;i<=n;i++) dp[i][i] = 1;
for(int j=0,v;j<=n;j++)
for(int i=1;i<=n;i++)
{
v=i-j;
if(v>=1)
{
for(int k=v;k<i;k++)
if(Map[i][k] && dp[k][v] && dp[k][i-1])
{
dp[i][v] = 1;
break;
}
}
v=i+j;
if(v<=n)
{
for(int k=i+1;k<=v;k++)
if(Map[i][k] && dp[k][i+1] && dp[k][v])
{
dp[i][v] = 1;
break;
}
}
}
for(int i=1;i<=n;i++)
if(dp[i][1] && dp[i][n])
{
puts("Yes");
return 0;
}
puts("No");
}