codeforces 1025D Recovering BST 区间DP

版权声明:本文为博主原创文章,转载请附上原博客链接。 https://blog.csdn.net/Dale_zero/article/details/82119270

题目链接:http://codeforces.com/problemset/problem/1025/D

开两个dp数组代表从i到j能否形成以i为根的右子树或者以j为根的左子树。

若有一位置到1和n均能形成左右子树则输出Yes,否则输出No

#include<bits/stdc++.h>
#define inf 0x3f3f3f3f
#define mod 1000000007
#define For(i,m,n) for(int i=m;i<=n;i++)
#define Dor(i,m,n) for(int i=m;i>=n;i--)
#define LL long long
#define lan(a,b) memset(a,b,sizeof(a))
#define sqr(a) a*a
using namespace std;

int dp[710][710][2];
int g[710][710];
int a[710];
    int n;
int gcd(int a,int b)
 {
     return b==0?a:gcd(b,a%b);
 }


bool pin()
{
     For(len,1,n)
        {
            for(int i=1;i+len-1<=n;i++)
            {
                if(len==1)
                    dp[i][i][0]=1,dp[i][i][1]=1;
                int j=i+len-1;
//                printf("i=%d j=%d\n",i,j);
                For(k,i,j)
                {
//                    printf("k=%d\n",k);
                    if(dp[i][k][0]==1&&dp[k][j][1]==1)
                    {
//                        cout<< "ok1" << endl;
                        if(i==1&&j==n)
                            return true;

                        if(j!=n&&g[k][j+1]==1)
                            dp[i][j+1][0]=1;///printf("dp[%d][%d][%d]=1\n",i,j+1,0);
                        if(i!=1&&g[i-1][k]==1)
                            dp[i-1][j][1]=1;///printf("dp[%d][%d][%d]=1\n",i-1,j,1);
                    }
                }
            }
        }
        return false;
}

int main()
{
    while(~scanf("%d",&n))
    {
        lan(dp,0);
        lan(a,0);
        lan(g,0);
        For(i,1,n)
            scanf("%d",&a[i]);
            For(i,1,n)
                For(j,i+1,n)
                    if(gcd(a[i],a[j])!=1)g[i][j]=1;
        sort(a+1,a+1+n);
        if(pin())
            printf("Yes\n");
        else
            printf("No\n");
    }
    return 0;
}

猜你喜欢

转载自blog.csdn.net/Dale_zero/article/details/82119270