• [测试题]删数方案数


    Description

    给出一个正整数序列 a,长度为 n,cyb 不喜欢完美,他要删掉一些数(也可以不删,即删掉0个),但是他不会乱删,他希望删去以后,能将 a 分成 2 个集合,使得两个非空集合的数的和相同,现在他希望你能帮他算出删数的方案数。

    Input

    第一行 n 个正整数

    以下有 n行,每行1个

    正整数表示整数序列a

    Output

    一个整数表示答案

    Sample Input

    4

    1 2 3 4

    Sample Output

    3

    Hint

    30%:n<=5

    100%:n<=20

    100%:a 中每个元素<=100000000

    题解

    涉及到了$hash$,状压,双向搜索
    首先可以想出一个$3^N$的搜索.
    枚举每个是不选还是在$A$集合,还是在$B$集合
    这样显然通不过$20$的数据
    那么我们发现这个搜索是独立的
    如果在$A$集合,我们令其为$-1*a$
    在$B$集合,令其为$1*a$
    那么实际上我们在找一个方程有多少组解.
    这样,我们先搜前面一半,将和用$hash$存起来
    将选的情况,用一个$2$进制数也存入$hash$
    这样可以通过全部数据

     1 #include<map>
     2 #include<cmath>
     3 #include<ctime>
     4 #include<queue>
     5 #include<stack>
     6 #include<vector>
     7 #include<cstdio>
     8 #include<string>
     9 #include<cstdlib>
    10 #include<cstring>
    11 #include<iostream>
    12 #include<algorithm>
    13 #define LL long long
    14 #define RE register
    15 #define IL inline
    16 using namespace std;
    17 const int MOD=1e6+7;
    18 
    19 int n,lim;
    20 int a[25];
    21 int ans;
    22 bool vis[(1<<21)+5];
    23 struct HASH
    24 {
    25     int to,next,st;
    26 }edge[MOD+5];
    27 int path[MOD+5],top;
    28 
    29 void find_hash(int a,int st)
    30 {
    31     int k=(a%MOD+MOD)%MOD;
    32     for (RE int i=path[k];i;i=edge[i].next) if (edge[i].to==a) vis[edge[i].st+st]=1;
    33 }
    34 void push_hash(int a,int st)
    35 {
    36     int k=(a%MOD+MOD)%MOD;
    37     edge[++top].to=a;
    38     edge[top].st=st;
    39     edge[top].next=path[k];
    40     path[k]=top;
    41 }
    42 
    43 void Dfs(int cen,int tol,int set)
    44 {
    45     if (cen>lim)
    46     {
    47         push_hash(tol,set);
    48         return;
    49     }
    50     Dfs(cen+1,tol,set);
    51     Dfs(cen+1,tol+a[cen],set+(1<<cen-1));
    52     Dfs(cen+1,tol-a[cen],set+(1<<cen-1));
    53 }
    54 void Dfs2(int cen,int tol,int set)
    55 {
    56     if (cen<=lim)
    57     {
    58         find_hash(tol,set);
    59         return;
    60     }
    61     Dfs2(cen-1,tol,set);
    62     Dfs2(cen-1,tol+a[cen],set+(1<<cen-1));
    63     Dfs2(cen-1,tol-a[cen],set+(1<<cen-1));
    64 }
    65 
    66 int main()
    67 {
    68     scanf("%d",&n);lim=n/2;
    69     for (RE int i=1;i<=n;i++) scanf("%d",&a[i]);
    70     Dfs(1,0,0);
    71     Dfs2(n,0,0);
    72     for (RE int i=1;i<(1<<n);i++) ans+=vis[i];
    73     printf("%d",ans);
    74     return 0;
    75 }
  • 相关阅读:
    安装composer后报错proc_open(): fork failed
    ZOJ4063 Tournament [The 2018 ACM-ICPC Asia Qingdao Regional Contest]
    BZOJ1191: [HNOI2006]超级英雄Hero
    BZOJ1270: [BeijingWc2008]雷涛的小猫
    BZOJ1303 [CQOI2009]中位数图
    BZOJ1192 [HNOI2006]鬼谷子的钱袋
    BZOJ1003 [ZJOI2006]物流运输 最短路+DP
    牛客国庆集训派对Day6 E-Growth
    BZOJ2208 [Jsoi2010]连通数
    BZOJ2761 [JLOI2011]不重复数字
  • 原文地址:https://www.cnblogs.com/NaVi-Awson/p/7358518.html
Copyright © 2020-2023  润新知