• 洛谷3067 BZOJ 2679题解(折半搜索)


    传送门

    BZOJ传送门(权限题)

    看到n小于20,就可以想到搜索

    所有的数要么在集合a中,要么在集合b中,要么都不在

    可是3^n复杂度会炸,我们考虑优化

    可以利用折半搜索,将前面一半的所有可能情况与后一半列举

    排序扫描统计答案

    由于选择情况可能会重复,我们还要记录一下状态,然后在统计时判断一下

    统计时会将一个都不选的情况计算进去,所以ans要-1

    # include<iostream>
    # include<cstdio>
    # include<cmath>
    # include<algorithm>
    # include<cstring>
    using std::sort;
    const int mn = 21;
    int a[mn];
    int n;
    struct node{int val,cur;};
    node L[1<<mn],R[1<<mn];
    int vis[1<<mn];
    int LeftCnt,RightCnt;
    void dfs(int x,int en,int nowval,int nowstate)
    {
        if(x>en)
        {
            if(en==n/2)    L[++LeftCnt].val=nowval,L[LeftCnt].cur=nowstate;
            else R[++RightCnt].val=nowval,R[RightCnt].cur=nowstate;
            return ;
        }
        dfs(x+1,en,nowval,nowstate);
        dfs(x+1,en,nowval-a[x],nowstate+(1<<(x-1)));
        dfs(x+1,en,nowval+a[x],nowstate+(1<<(x-1)));
    }
    bool cmp1(node x,node y){return x.val<y.val;}
    bool cmp2(node x,node y){return x.val>y.val;}
    int main()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%d",&a[i]);
        dfs(1,n/2,0,0);
        dfs(n/2+1,n,0,0);
        sort(L+1,L+1+LeftCnt,cmp1);
        sort(R+1,R+1+RightCnt,cmp2);
        int l=1,r=1,ans=0;
        while(l<=LeftCnt && r<=RightCnt)
        {
              while(L[l].val+R[r].val>0 && r<=RightCnt) r++;
              int pre=r;
              while(L[l].val+R[r].val==0 && r<=RightCnt)
              {
                  if(vis[L[l].cur | R[r].cur]==0)
                     vis[L[l].cur | R[r].cur]=1,ans++;
                  r++;
              }
              if(L[l].val==L[l+1].val)     r=pre;
              l++;
        }
        printf("%d",ans-1);
        return 0;
    }
  • 相关阅读:
    光盘和U盘
    解决时间同步
    僵尸进程 和 孤儿进程
    Centos虚拟机设置网络模式
    常用CDN 和 后台管理模板
    微信小程序wxs如何使用
    kubernetes/client-go--使用 Clientset 获取 Kubernetes 资源对象
    samplecontroller
    volcano
    DNS欺骗
  • 原文地址:https://www.cnblogs.com/logeadd/p/9007794.html
Copyright © 2020-2023  润新知