• 51NOD 1400 序列分解


    传送门:序列分解

    基准时间限制:1s  空间限制:131072KB
             
     

    小刀和大刀是双胞胎兄弟。今天他们玩一个有意思的游戏。 大刀给小刀准备了一个长度为 $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 递归地扩展出一棵解答树。节点(DFS)参数为 $(i, j, k)$ ,表示当前两子序列待确定 (active) 列中可
    用(active) 的位置是 $k$ 。(其实 $k$ 是可有可无的参数,因为 $k = i+j-1$ ,但添上也无妨)代码中加上了一些剪枝。
    不失一般性,可认为原序列的首元素属于第一个子序列,因此初始调用参数可设为 $( 2, 1, 2)$ 。

    P.S. 考虑这个问题时,没想出非暴力的解法,只是看出:
    如果原序列可分成两个相等的子列,那么原序列的首、尾一定也是子列的首、尾
    若有更好的解法,望在评论里告知。
     1 #include<bits/stdc++.h>
     2 using namespace std;
     3 int a[50], N, x[50], y[50];
     4 bool dfs(int i, int j, int k){
     5     bool res;
     6     if(k>N) return true;
     7     if(i>N>>1){
     8         return a[k]==x[j]?y[j]=a[k], dfs(i, j+1, k+1):false;
     9     }
    10     if(j>N>>1){
    11         return a[k]==y[i]?x[i]=a[k], dfs(i+1, j, k+1):false;
    12     }
    13     if(i==j){
    14         x[i]=a[k];
    15         if(dfs(i+1, j, k+1)) return true;
    16         y[j]=a[k];
    17         return dfs(i, j+1, k+1);
    18     }
    19     if(i>j){
    20         res = x[j]==a[k]?y[j]=a[k],dfs(i, j+1, k+1):false;
    21         if(res) return res;
    22         return x[i]=a[k],dfs(i+1, j, k+1);
    23     }
    24     if(j>i){
    25         res = y[i]==a[k]?x[i]=a[k],dfs(i+1, j, k+1):false;
    26         if(res) return res;
    27         return y[j]=a[k],dfs(i, j+1, k+1);
    28     }
    29 }
    30 int main(){
    31     //freopen("in", "r", stdin);
    32     int T;
    33     scanf("%d", &T);
    34     while(T--){
    35         scanf("%d", &N);
    36         int res=0;
    37         for(int i=1; i<=N; i++) scanf("%d", a+i), res^=a[i];
    38         if(res){
    39             puts("What a pity!");
    40             continue;
    41         }
    42         x[1]=a[1];
    43         puts(dfs(2, 1, 2)?"Good job!!":"What a pity!");
    44     }
    45     return 0;
    46 }
    
    
  • 相关阅读:
    docker 安装 clickhouse单机版
    CockRoachDB简介
    Ubuntu18.04 LTS Cockroach集群搭建
    ClickHouse 的一些优化参数
    ClickHouse 概念整理
    OOM Killer机制
    win10系统下载地址
    Quartz.Net在C#中的使用
    JavaScript的undefined与null、NaN的区别
    Java Web基础回顾 —JSP
  • 原文地址:https://www.cnblogs.com/Patt/p/4677136.html
Copyright © 2020-2023  润新知