http://codeforces.com/contest/1025/problem/D
树 dp 优化
f[x][y][0]=f[x][z][1] & f[z+1][y][0] ( gcd(a[x-1],a[z])<>0 )
f[x][y][1]=f[x][z][1] & f[z+1][y][0] ( gcd(a[z],a[y+1])<>0 )
1 #include <cstdio> 2 #include <cstdlib> 3 #include <cmath> 4 #include <cstring> 5 #include <time.h> 6 #include <string> 7 #include <set> 8 #include <map> 9 #include <list> 10 #include <stack> 11 #include <queue> 12 #include <vector> 13 #include <bitset> 14 #include <ext/rope> 15 #include <algorithm> 16 #include <iostream> 17 using namespace std; 18 #define ll long long 19 #define minv 1e-6 20 #define inf 1e9 21 #define pi 3.1415926536 22 #define E 2.7182818284 23 const ll mod=1e9+7;//998244353 24 const int maxn=1e3+10; 25 26 int a[maxn]; 27 bool vis[maxn][maxn]={0},f[maxn][maxn][2]={0}; 28 29 int main() 30 { 31 int n,i,j,x,y,z; 32 scanf("%d",&n); 33 for (i=1;i<=n;i++) 34 scanf("%d",&a[i]); 35 for (i=1;i<n;i++) 36 for (j=i+1;j<=n;j++) 37 vis[i][j]=(__gcd(a[i],a[j])!=1); 38 for (i=0;i<=n;i++) 39 vis[0][i]=1,vis[i][n+1]=1; 40 for (i=1;i<=n+1;i++) 41 f[i][i-1][0]=f[i][i-1][1]=1; 42 for (i=1;i<=n;i++) 43 for (x=1,y=i;x<=n-i+1;x++,y++) 44 for (z=x;z<=y;z++) 45 if (f[x][z-1][1] && f[z+1][y][0]) 46 { 47 if (vis[x-1][z]) 48 f[x][y][0]=1; 49 if (vis[z][y+1]) 50 f[x][y][1]=1; 51 } 52 if (f[1][n][0]) 53 printf("Yes"); 54 else 55 printf("No"); 56 return 0; 57 }