51nod-序列分解(dfs)

来源:互联网 发布:js监听键盘 编辑:程序博客网 时间:2024/05/05 14:45
1400 序列分解
基准时间限制: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示例
241 1 2 261 2 3 4 5 6
Output示例
Good job!!What a pity!
System Message (题目提供者)
题解:

从第一个数字开始搜索,当前数字有两种情况,

第一,该数字没有出现过则一定存在于第一个序列

第二,改数字出现过,择优两种选择,第一个序列第二个序列都有可能存在

则分别dfs即可

#include<stdio.h>#include<string.h>#include<algorithm>using namespace std;typedef long long ll;ll a[55],b[55],c[55];ll n,flag;void dfs(ll id,ll len1,ll len2,ll x)//id表示当前遍历到第i个数字//len1,len2分别表示两个序列当前的长度//x表示当前匹配到第一个子序列的第x个数字{if(len1>n/2+1 || len2>n/2+1 || flag)return;if(id==n+1){if(len1==len2)flag=1;return;}if(id==1){b[len1]=a[id];dfs(id+1,len1+1,len2,x);}else{if(a[id]==b[x]){c[len2]=a[id];dfs(id+1,len1,len2+1,x+1);}b[len1]=a[id];dfs(id+1,len1+1,len2,x);}return;}int  main(){ll T,i;scanf("%lld",&T);while(T--){flag=0;memset(b,0,sizeof(b));memset(c,0,sizeof(c));scanf("%lld",&n);for(i=1;i<=n;i++)scanf("%lld",&a[i]);dfs(1,1,1,1);if(flag)printf("Good job!!\n");elseprintf("What a pity!\n");}}


0 0