zoukankan      html  css  js  c++  java
  • SPOJ11469 SUBSET

    题面

    Farmer John's owns N cows (2 <= N <= 20), where cow i produces M(i) units of milk each day (1 <= M(i) <= 100,000,000).

    FJ wants to streamline the process of milking his cows every day, so he installs a brand new milking machine in his barn.

    Unfortunately, the machine turns out to be far too sensitive: it only works properly if the cows on the left side of the

    barn have the exact same total milk output as the cows on the right side of the barn!

    Let us call a subset of cows "balanced" if it can be partitioned into two groups having equal milk output.

    Since only a balanced subset of cows can make the milking machine work, FJ wonders how many subsets of his N cows are balanced.

    Please help him compute this quantity.

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

    题解

    我在考场上打的是暴力(3^n)我不会告诉你我CE了

    我们可以(3^{n/2})枚举两边的子集,然后(meeting;in;the;middle)即可

    代码

    #include<cstdio>
    #include<map>
    #include<vector>
    #define RG register
    #define clear(x, y) memset(x, y, sizeof(x));
    
    inline int read()
    {
    	int data = 0, w = 1;
    	char ch = getchar();
    	while(ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
    	if(ch == '-') w = -1, ch = getchar();
    	while(ch >= '0' && ch <= '9') data = data * 10 + (ch ^ 48), ch = getchar();
    	return data*w;
    }
    
    const int maxn(21);
    int n, a[maxn], ok[1 << maxn], cnt, ans;
    
    typedef std::vector<int>::iterator iter;
    std::map<int, int> map;
    std::vector<int> set[1 << maxn];
    
    void dfs(int x, int s, int d)
    {
    	if(x > (n >> 1) - 1)
    	{
    		if(map.find(d) == map.end()) map[d] = ++cnt;
    		int t = map[d]; set[t].push_back(s); return;
    	}
    
    	dfs(x + 1, s, d);
    	dfs(x + 1, s | (1 << x), d + a[x]);
    	dfs(x + 1, s | (1 << x), d - a[x]);
    }
    
    void Dfs(int x, int s, int d)
    {
    	if(x > n - 1)
    	{
    		if(map.find(d) == map.end()) return;
    		int t = map[d];
    		for(RG iter it = set[t].begin(); it != set[t].end(); ++it) ok[(*it) | s] = 1;
    		return;
    	}
    
    	Dfs(x + 1, s, d);
    	Dfs(x + 1, s | (1 << x), d + a[x]);
    	Dfs(x + 1, s | (1 << x), d - a[x]);
    }
    
    int main()
    {
    	n = read();
    	for(RG int i = 0; i < n; i++) a[i] = read();
    	dfs(0, 0, 0); Dfs((n >> 1), 0, 0);
    	for(RG int i = (1 << n) - 1; i; i--) ans += ok[i];
    	printf("%d
    ", ans);
    	return 0;
    }
    
  • 相关阅读:
    [POI2010]Divine Divisor
    JOISC2014B たのしい家庭菜園
    Problem. C
    AGC004F Namori
    AGC007F Shik and Copying String
    AGC027C ABland Yard
    AGC028E High Elements
    JOI2017FinalE 縄
    CF797F Mice and Holes
    Problem. B
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/9798648.html
Copyright © 2011-2022 走看看