1400 序列分解(dfs)

基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题

小刀和大刀是双胞胎兄弟。今天他们玩一个有意思的游戏。 大刀给小刀准备了一个长度为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 }
View Code

 



posted @ 2017-10-03 12:26  happy_codes  阅读(322)  评论(0编辑  收藏  举报