1400 序列分解(dfs)
小刀和大刀是双胞胎兄弟。今天他们玩一个有意思的游戏。 大刀给小刀准备了一个长度为n的整数序列。小刀试着把这个序列分解成两个长度为n/2的子序列。
这两个子序列必须满足以下两个条件:
1.他们不能相互重叠。
2.他们要完全一样。
如果小刀可以分解成功,大刀会给小刀一些糖果。
然而这个问题对于小刀来说太难了。他想请你来帮忙。
Input
第一行给出一个T,表示T组数据。(1<=T<=5)
接下来每一组数据,输入共2行。
第一行包含一个整数n (2<=n<=40且为偶数)。
第二行给出n个整数a[0],a[1],a[2],…,a[n-1]表示大刀给小刀准备的序列。(-1,000,000,000<=a[i]<=1,000,000,000)
Output
如果小刀可以完成游戏,输出"Good job!!" (不包含引号),否则 输出"What a pity!" (不包含引号)。
Input示例
2
4
1 1 2 2
6
1 2 3 4 5 6
Output示例
Good job!!
What a pity!
//难懂的题意,看了讨论才知道,就是说将大序列分成两个子序列,子序列的顺序关系不能改变,
那么没想到什么好办法,玄学dfs走一波,算起来复杂度高,实际是不怎么高的,毕竟要相同才能移动,想清楚即可
1 #include <bits/stdc++.h> 2 using namespace std; 3 #define INF 0x3f3f3f3f 4 #define LL long long 5 #define MX 45 6 7 int n; 8 int dat[MX]; 9 bool vis[MX]; 10 11 int dfs(int x, int y, int s) 12 { 13 if (s==n/2) return 1; 14 vis[x]=1, vis[y]=1; 15 int _x = x+1, _y = y+1; 16 while (_x<=n&&vis[_x]) _x++; 17 while(1) 18 { 19 while (_y<=n&&(vis[_y]||_y==_x||dat[_x]!=dat[_y])) _y++; 20 if (_x<=n&&_y<=n) 21 { 22 if (dfs(_x,_y,s+1)) 23 return 1; 24 _y++; 25 } 26 else break; 27 } 28 vis[x]=0, vis[y]=0; 29 return 0; 30 } 31 32 int main() 33 { 34 int T; 35 scanf("%d",&T); 36 while (T--) 37 { 38 memset(vis,0,sizeof(vis)); 39 scanf("%d",&n); 40 for (int i=1;i<=n;i++) 41 scanf("%d",&dat[i]); 42 bool ok = 0; 43 for (int i=2;i<=n/2+1;i++) 44 { 45 if (dat[1]==dat[i]&&dfs(1,i,1)) 46 { 47 ok=1; 48 break; 49 } 50 } 51 if (ok) 52 printf("Good job!!\n"); 53 else 54 printf("What a pity!\n"); 55 } 56 }