题面

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\n", ans);
return 0;
}

SPOJ11469 SUBSET的更多相关文章

  1. SPOJ11469 Subset(折半枚举)

    题意 给定一个集合,有多少个非空子集,能划分成和相等的两份.\(n\leq 20\) 题解 看到这个题,首先能想到的是\(3^n\)的暴力枚举,枚举当前元素是放入左边还是放入右边或者根本不放,但是显然 ...

  2. [LeetCode] Partition Equal Subset Sum 相同子集和分割

    Given a non-empty array containing only positive integers, find if the array can be partitioned into ...

  3. [LeetCode] Largest Divisible Subset 最大可整除的子集合

    Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of ...

  4. 洛谷 P1466 集合 Subset Sums Label:DP

    题目描述 对于从1到N (1 <= N <= 39) 的连续整数集合,能划分成两个子集合,且保证每个集合的数字和是相等的.举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,每个子 ...

  5. LeetCode "Largest Divisible Subset" !

    Very nice DP problem. The key fact of a mutual-divisible subset: if a new number n, is divisible wit ...

  6. 【USACO 2.2】Subset Sums (DP)

    N (1 <= N <= 39),问有多少种把1到N划分为两个集合的方法使得两个集合的和相等. 如果总和为奇数,那么就是0种划分方案.否则用dp做. dp[i][j]表示前 i 个数划分到 ...

  7. Leetcode 416. Partition Equal Subset Sum

    Given a non-empty array containing only positive integers, find if the array can be partitioned into ...

  8. Leetcode 368. Largest Divisible Subset

    Given a set of distinct positive integers, find the largest subset such that every pair (Si, Sj) of ...

  9. ArcGIS制图之Subset工具点抽稀

    制图工作中,大量密集点显示是最常遇到的问题.其特点是分布可能不均匀.数据点比较密集,容易造成空间上的重叠,影响制图美观.那么,如果美观而详细的显示制图呢? Subset Features(子集要素)工 ...

随机推荐

  1. C#关于递归等等

    递归的例子1 计算1到100相加的值 public partial class Default4 : System.Web.UI.Page{    protected void Page_Load(o ...

  2. c++ 有swap函数

    这是剑指offer数组中重复的数字那个题,直接使用的swap函数 class Solution { public: // Parameters: // numbers: an array of int ...

  3. Git删除commit提交的log记录

    基于 GitFlow 工作流,可能某个提交(commit)导致了 bug,或者有多个提交需要返工,此时你就会用到删除提交. 接下来的内容都基于下面这张 git log 提交记录图来写.   git l ...

  4. PAT——1057. 数零壹

    给定一串长度不超过105的字符串,本题要求你将其中所有英文字母的序号(字母a-z对应序号1-26,不分大小写)相加,得到整数N,然后再分析一下N的二进制表示中有多少0.多少1.例如给定字符串“PAT ...

  5. CocoaPods安装指定版本

    Cocoapods目前最新的正式版本是0.35.0,如果升级到这个版本,并且在project中使用XMPPFramework,在pod install之后会出现如下循环依赖的问题 There is a ...

  6. 【腾讯敏捷转型No.2】帅哥,来多少敏捷?

    上回腾讯敏捷转型系列第一篇文章<敏捷到底是什么鬼?>讲到公司铁了心要推进敏捷,这是战略层面的决定,为什么呢? 当时的我们并不知道公司为什么一定要推行敏捷的新概念,但是后来公司的变化帮助我们 ...

  7. Autolayout中Hugging和Compression使用注意

    前言 本文主要侧重Autolayout使用过程中,通过代码和SB添加含有intrinsicSize属性控件约束的一些细节. 来自我的博客,欢迎访问:To Be Independent. Hugging ...

  8. nodejs中npm以及yarn常用指令

    1.npm下载相关 1.npm install/i vue //下载vue的包 2.npm i vue --save-dev / -D //下载vue的包,并添加到开发依赖中 3.npm i //下载 ...

  9. 【学时总结】 ◆学时·III◆ 二分图

    [学时·III] 二分图 ■基本策略■ 其实本质是图论中的网络流 二分图是两个由多个点组成的集合(上部和下部,且没有重叠),两个集合中的点不与该集合内其他的点连通,但和另一个集合内的点连通.我们称这两 ...

  10. JQuery中事件冒泡

    JQuery中事件冒泡 定义 在一个对象上触发某类事件,就会执行此事件程序,如果没有处理事件就会向这个对象的父级对象传播 直至它被处理,最顶层老大为document对象. 作用 事件冒泡允许多个操作被 ...