zoukankan      html  css  js  c++  java
  • USACO 2012 OPEN GOLD subsets(Meet-In-The-Middle)

    Problem

    有多少个非空子集,能划分成和相等的两份。

    Solution

    直接对于这n个数分成左右两个部分,然后考虑每一个数:

    1. 在第一个集合
    2. 在第二个集合
    3. 两个集合都不在

    所以可以直接对于这个东西搞一个Map和一个Set存一下,考虑把左边的和和右边的和分别抠出来,然后搞一下就可以了。

    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #include<math.h>
    #include<iostream>
    #include<queue>
    #include<algorithm>
    #include<set>
    #include<map>
    #define ll long long
    #define file(a) freopen(a".in","r",stdin);freopen(a".out","w",stdout)
    using namespace std;
    inline int gi(){
    	int sum=0,f=1;char ch=getchar();
    	while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    	return f*sum;
    }
    inline ll gl(){
    	ll sum=0,f=1;char ch=getchar();
    	while(ch>'9' || ch<'0'){if(ch=='-')f=-1;ch=getchar();}
    	while(ch>='0' && ch<='9'){sum=(sum<<3)+(sum<<1)+ch-'0';ch=getchar();}
    	return f*sum;
    }
    int dp[2000010],m[30],n,f[2000010],ans,vis[30],cnt;
    map<int,int>M;
    set<int>S[2000010];
    void dfs1(int i,int s,int d){
    	if(i==n/2){
    		if(M.find(d)==M.end())M[d]=++cnt;
    		int t=M[d];
    		S[t].insert(s);
    		return;
    	}
    	dfs1(i+1,s,d);
    	dfs1(i+1,s|(1<<i),d+m[i]);
    	dfs1(i+1,s|(1<<i),d-m[i]);
    }
    void dfs2(int i,int s,int d){
    	if(i>n-1){
    		if(M.find(d)==M.end())return;
    		int t=M[d];
    		set<int>::iterator it;
    		for(it=S[t].begin();it!=S[t].end();it++)
    			dp[(*it)|s]=1;
    		return;
    	}
    	dfs2(i+1,s,d);
    	dfs2(i+1,s|(1<<i),d+m[i]);
    	dfs2(i+1,s|(1<<i),d-m[i]);
    }
    int main(){
    	file("subsets");
            int i,j,k;
    	n=gi();
    	for(i=0;i<n;i++)m[i]=gi();
    	dfs1(0,0,0);
    	dfs2(n/2,0,0);
    	for(i=1;i<1<<n;i++)ans+=dp[i];
    	printf("%d
    ",ans);
    	return 0;
    }
    
  • 相关阅读:
    linux解压分卷压缩的zip文件
    centos关闭sudo的ldap认证
    IT词汇表
    IT博客汇
    os.waitpid()无法获取sys.exit()退出时的status code
    github下fork后如何同步源的新更新
    git 撤销commit
    g++编译问题:skipping incompatible /usr/lib//libboost_system.so when searching for -lboost_system
    g++动态库静态库混合链接
    thread
  • 原文地址:https://www.cnblogs.com/cjgjh/p/9798029.html
Copyright © 2011-2022 走看看