D. Recovering BST(dp+記憶化搜索)

Dima the hamster enjoys nibbling different things: cages, sticks, bad problemsetters and even trees!

Recently he found a binary search tree and instinctively nibbled all of its edges, hence messing up the vertices. Dima knows that if Andrew, who has been thoroughly assembling the tree for a long time, comes home and sees his creation demolished, he'll get extremely upset.

To not let that happen, Dima has to recover the binary search tree. Luckily, he noticed that any two vertices connected by a direct edge had their greatest common divisor value exceed 11.

Help Dima construct such a binary search tree or determine that it's impossible. The definition and properties of a binary search tree can be found here.

Input

The first line contains the number of vertices nn (2≤n≤7002≤n≤700).

The second line features nn distinct integers aiai (2≤ai≤1092≤ai≤109) — the values of vertices in ascending order.

Output

If it is possible to reassemble the binary search tree, such that the greatest common divisor of any two vertices connected by the edge is greater than 11, print "Yes" (quotes for clarity).

Otherwise, print "No" (quotes for clarity).

Examples

input

6
3 6 9 18 36 108

output

Yes

input

2
7 17

output

No

input

9
4 8 10 12 15 18 33 44 81

output

Yes

題目大概:

給出n個數,按升序給出,組成一顆二叉樹,每兩個相連節點之間必須有公約數。問是否能夠組成這棵樹。

思路:

預處理一下互質的數。

枚舉根,dfs左右區間,dp+記憶化搜索看是否能找出一組解。

代碼:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int maxn=800;
const int INF=1e9+7;
const int mod=1e9+7;
int a[maxn];
int zh[maxn][maxn];
int dp[maxn][maxn][2];
int vis[maxn][maxn][2];

int dfs(int l,int r,int k)
{
    if(l>r)return 1;
    if(vis[l][r][k])return dp[l][r][k];
    int flag;
    if(!k)flag=r+1;
    else flag=l-1;
    int flag1=0;
    for(int i=l;i<=r;i++)
    {
        if(!zh[i][flag]&&dfs(l,i-1,0)&&dfs(i+1,r,1))
        {
            flag1=1;
            break;
        }
    }
    vis[l][r][k]=1;
    return dp[l][r][k]=flag1;
}
long long gcd(long long m, long long n)
{
    while(m>0)
    {
        long long c = n % m;
        n = m;
        m = c;
    }
    return n;
}
int main()
{
    int n;
    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;j<=n;j++)
        {
            if(gcd(a[i],a[j])==1)
            {
                zh[i][j]=zh[j][i]=1;
            }
        }
    }
    for(int i=1;i<=n;i++)
    {
        if(dfs(1,i-1,0)&&dfs(i+1,n,1))
        {
            printf("Yes\n");
            return 0;
        }
    }

    printf("No\n");
    return 0;
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章