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;
    }
    
  • 相关阅读:
    select.poll,epoll的区别与应用
    hibernate生成查询语句但查不到数据
    优化exp/imp导入导出速度大全
    完美逆向百度手机助手5.0底部菜单栏
    C#序列化和反序列化
    Centos6 编译安装局域网NTP服务器
    linux查看服务器型号
    fopen/fclose
    C文件操作之写入字符串到指定文件并在屏幕显示
    Centos6.x X64 飞信安装
  • 原文地址:https://www.cnblogs.com/cj-xxz/p/9798648.html
Copyright © 2011-2022 走看看