【区间DP】Codeforces#505D 1025D Recovering BST

题意

给n个数,问能否构造出一个相邻节点不互质的二叉搜索树。

题解

JZ太神了,看了一眼就说区间DP。

定义 lft[i][j] l f t [ i ] [ j ] 表示 [i,j] [ i , j ] 接在 i1 i − 1 的右儿子是否可行, rgt[i][j] r g t [ i ] [ j ] 表示 [i,j] [ i , j ] 接在 j+1 j + 1 的左儿子是否可行。转移就用经典区间DP,枚举 [i,j] [ i , j ] 中的一个作为根。

代码

#include
#include
#include
using namespace std;
const int maxn=706;
int n,a[maxn];
bool g[maxn][maxn],lft[maxn][maxn],rgt[maxn][maxn];
int gcd(int x,int y){return !y?x:gcd(y,x%y);}
int main(){
    freopen("D.in","r",stdin);freopen("D.out","w",stdout);
    scanf("%d",&n);for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;ifor(int j=i+1;j<=n;j++) if(gcd(a[i],a[j])>1)g[i][j]=g[j][i]=1;
    for(int i=1;i<=n;i++)g[0][i]=g[i][0]=g[i][n+1]=g[n+1][i]=1;
    for(int i=n;i>=1;i--)
     for(int j=i;j<=n;j++)
      for(int k=i;k<=j;k++) if((k==i||rgt[i][k-1])&&(k==j||lft[k+1][j]))lft[i][j]|=g[k][i-1],rgt[i][j]|=g[k][j+1];
    for(int i=1;i<=n;i++) if((i==1||rgt[1][i-1])&&(i==n||lft[i+1][n]))return puts("Yes"),0;
    return puts("No"),0;
}

你可能感兴趣的:(Codeforces,区间DP)