暴搜——51nod1400 序列分解

来源:互联网 发布:国安数据 编辑:程序博客网 时间:2024/05/17 14:17

题面:51nod1400
真的是大暴力
有人说直接暴搜加一个小剪枝就能过。。。
我的搜索策略有点奇怪


先讲一个错误的贪心:
我们开个数组q[i]记录一个子序列的状态
用一个指针p表示另一个子序列目前匹配到q[i]的第几位
然后匹配下一位的时候往后找到和这一位数值相同的最近位置
然后匹配上就好了,复杂度O(n)
但是这是错的,比如这组数据:

8
1 1 4 3 1 1 4 3

这就不行了
但是我们不要直接匹配上去,有两条路可以走,一是匹配,二是继续在前面一个串跟上去
这样就有两种策略了,搜索即可
时间复杂度O(2n2)
反正过了

#include <cstdio>#include <algorithm>#include <cmath>#include <cstring>#include <iostream>#include <ctime>#include <map>#include <queue>#include <cstdlib>#include <string>#include <climits>#include <set>#include <vector>using namespace std;inline int read(){    int k=0,f=1;char ch=getchar();    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}    while(ch>='0'&&ch<='9'){k=k*10+ch-'0';ch=getchar();}    return k*f;}int a[10001],q[10001],n;inline bool dfs(int l,int p,int r){    if(p==l)q[++l]=a[r++];    if(l>n/2)return 0;    while(q[p+1]!=a[r]){        q[++l]=a[r];r++;        if(r>n)return 0;    }    if(r==n&&p+1==l)return 1;    if(dfs(l,p+1,r+1))return 1;    else{        q[l+1]=a[r];        return dfs(l+1,p,r+1);    }}int main(){    int T=read();while(T--){        n=read();        for(int i=1;i<=n;i++)a[i]=read();        q[1]=a[1];        puts(dfs(1,0,2)?"Good job!!":"What a pity!");    }    return 0;}