• P3067 [USACO12OPEN]Balanced Cow Subsets G


    P3067 [USACO12OPEN]Balanced Cow Subsets G

    折半搜索。

    发现数据范围很小,但是直接搜索不现实,于是考虑折半搜索。

    折半搜索本质就是只搜一半然后把两个答案拼起来。

    这里注意要二进制压缩状态来判断重复。

    代码:

    #include<bits/stdc++.h>
    using namespace std;
    template <typename T>
    inline void read(T &x){
    	x=0;char ch=getchar();bool f=false;
    	while(!isdigit(ch)){if(ch=='-'){f=true;}ch=getchar();}
    	while(isdigit(ch)){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}
    	x=f?-x:x;
    	return ;
    }
    template <typename T>
    inline void write(T x){
    	if(x<0) putchar('-'),x=-x;
    	if(x>9) write(x/10);
    	putchar(x%10^48);
    	return ;
    }
    const int N=2e6+5;
    int n,n1,a[21],ans[N],s,tot;
    vector<int> p[N];
    map<int,int> b;
    void dfs1(int x,int sum,int now){
    	if(x>n1){
    		if(b[sum]==0) b[sum]=++tot;
    		p[b[sum]].push_back(now);
    		return;
    	}
    	dfs1(x+1,sum+a[x],now|(1<<(x-1))); 
        dfs1(x+1,sum-a[x],now|(1<<(x-1)));  
        dfs1(x+1,sum,now);
    } 
    void dfs2(int x,int sum,int now){
    	if(x>n){ 
    		int t=b[sum];
    		if(t!=0)  for(int i=0;i<p[t].size();i++)  ans[p[t][i]|now]=1;
    		return;
    	}
    	dfs2(x+1,sum+a[x],now|(1<<(x-1)));  
        dfs2(x+1,sum-a[x],now|(1<<(x-1)));  
        dfs2(x+1,sum,now);
    } 
    int main(){
    	read(n);
    	n1=n/2;
    	for(int i=1;i<=n;i++) read(a[i]);
    	dfs1(1,0,0);
    	dfs2(n1+1,0,0);
    	for(int i=1;i<=(1<<n);i++) s+=ans[i];
    	write(s);
    	return 0;
    } 
    
  • 相关阅读:
    SQLite的sqlite_sequence表
    缓存区溢出漏洞工具Doona
    SQLite的sqlite_master表
    dfs1321
    三维bfs(HUD1253胜利大逃亡)
    dfs模版
    poj3259: Wormholes(BF模板题)
    Bellman-Ford算法
    POJ1611:The Suspects(模板题)
    poj3126
  • 原文地址:https://www.cnblogs.com/Akmaey/p/14683236.html
Copyright © 2020-2023  润新知