• bzoj2679:[Usaco2012 Open]Balanced Cow Subsets


    思路:折半搜索,每个数的状态只有三种:不选、选入集合A、选入集合B,然后就暴搜出其中一半,插入hash表,然后再暴搜另一半,在hash表里查找就好了。

    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    using namespace std;
    #define maxn 25
     
    int n;
    int a[maxn],t[maxn];
    bool v[1025][1025];
    int ans;
     
    struct hash_table{
        static const int mod=242354;
        int tot,now[mod],pre[1000000],son[1000000],val[1000000];
        void insert(int t,int x){
            int pos=(x%mod+mod)%mod;
            for (int p=now[pos];p;p=pre[p]) if (son[p]==t&&val[p]==x) return;
            son[++tot]=t,val[tot]=x,pre[tot]=now[pos],now[pos]=tot;
        }
        int find(int t,int x){
            int pos=(x%mod+mod)%mod,ans=0;
            for (int p=now[pos];p;p=pre[p])
                if (val[p]==x&&!v[son[p]][t]){v[son[p]][t]=1;ans++;}
            return ans;
        }
    }H;
     
    void dfs1(int x,int val){
        if (x>n/2){
            int tmp=0;for (int i=1;i<=n/2;i++) tmp=tmp<<1|t[i];
            H.insert(tmp,val);return;
        }
        t[x]=1;dfs1(x+1,val+a[x]);
        t[x]=0;dfs1(x+1,val);
        t[x]=1;dfs1(x+1,val-a[x]);
    }
     
    void dfs2(int x,int val){
        if (x>n){
            int tmp=0;for (int i=n/2+1;i<=n;i++) tmp=tmp<<1|t[i];
            ans+=H.find(tmp,val);
            return;
        }
        t[x]=1;dfs2(x+1,val+a[x]);
        t[x]=0;dfs2(x+1,val);
        t[x]=1;dfs2(x+1,val-a[x]);
    }
     
    int main(){
        scanf("%d",&n);
        for (int i=1;i<=n;i++) scanf("%d",&a[i]);
        dfs1(1,0),dfs2(n/2+1,0);
        printf("%d
    ",ans-1);
        return 0;
    }
    
  • 相关阅读:
    SQL2005 镜像配置
    子窗体关闭程序
    asp.net 输出微信自定义菜单json
    教是最好的学
    人为什么要努力?
    《雪国列车》制度与自由
    时间记录APP———Time Meter
    饭饭
    Android编译程序报错:Re-installation failed due to different application signatures.
    我的GTD起步
  • 原文地址:https://www.cnblogs.com/DUXT/p/6007126.html
Copyright © 2020-2023  润新知