【Codeforces】Gym 101173B Bipartite Blanket 霍尔定理+状压DP
题意
给一张$n\times m$二分图,带点权,问有多少完美匹配子集满足权值和大于等于$t$
这里有一个结论:对于二分图$\mathbb{A}$和$\mathbb{B}$集合,如果子集$A \in \mathbb{A},B \in \mathbb{B}$,且$A,B$分别是完美匹配的子集,那么$A \cup B$属于一个完美匹配
有了这个结论之后,考虑单侧,枚举子集$S$,利用霍尔定理判定$S$是否是完美匹配,并通过dp转移状态,记录下单侧所有满足条件的权值和,然后两侧一起考虑累加得到答案
时间复杂度$O((n+m)2^{max(n,m)})$
代码
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N = 1 << 20;
int n, m, a[N + 5], b[N + 5], cnt[N + 5], L[N + 5], R[N + 5], fl[N + 5], fr[N + 5], t;
char str[100][100];
vector<int> g1, g2;
int main() {
    scanf("%d%d", &n, &m);
    for(int i = 0; i < n; ++i) scanf("%s", str[i]);
    for(int i = 0; i < n; ++i) scanf("%d", &a[i]);
    for(int i = 0; i < m; ++i) scanf("%d", &b[i]);
    for(int i = 0; i < n; ++i) {
        for(int j = 0; j < m; ++j) {
            if(str[i][j] == '1') {
                L[i] |= (1 << j); R[j] |= (1 << i);
            }
        }
    }
    scanf("%d", &t);
    for(int i = 0; i <= max((1 << n), (1 << m)); ++i) cnt[i] = cnt[i>>1] + (i & 1);
    for(int s = 0; s < (1 << n); ++s) {
        int now = 0, v = 0;
        fl[s] = 1;
        for(int i = 0; i < n; ++i) {
            if((s >> i) & 1) {
                v += a[i]; now |= L[i];
                fl[s] &= fl[s ^ (1 << i)];
            }
        }
        if(fl[s] && cnt[s] <= cnt[now]) g1.push_back(v);
        else fl[s] = 0;
    }
    for(int s = 0; s < (1 << m); ++s) {
        int now = 0, v = 0;
        fr[s] = 1;
        for(int i = 0; i < m; ++i) {
            if((s >> i) & 1) {
                v += b[i]; now |= R[i];
                fr[s] &= fr[s ^ (1 << i)];
            }
        }
        if(fr[s] && cnt[s] <= cnt[now]) g2.push_back(v);
        else fr[s] = 0;
    }
    sort(g1.begin(), g1.end());
    LL ans = 0;
    for(int i = 0; i < g2.size(); ++i) {
        ans += g1.size() - (lower_bound(g1.begin(), g1.end(), t - g2[i]) - g1.begin());
    }
    cout << ans << endl;
    return 0;
}
/*
3 3
010
111
010
1 2 3
8 5 13
21
 */
/*
3 2
01
11
10
1 2 3
4 5
8
 */
【Codeforces】Gym 101173B Bipartite Blanket 霍尔定理+状压DP的更多相关文章
- Codeforces Gym 100610 Problem K. Kitchen Robot 状压DP
		Problem K. Kitchen Robot Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codeforces.com/gym/10061 ... 
- Educational Codeforces Round 13 E. Another Sith Tournament 状压dp
		E. Another Sith Tournament 题目连接: http://www.codeforces.com/contest/678/problem/E Description The rul ... 
- Codeforces 1225G - To Make 1(bitset+状压 dp+找性质)
		Codeforces 题目传送门 & 洛谷题目传送门 还是做题做太少了啊--碰到这种题一点感觉都没有-- 首先我们来证明一件事情,那就是存在一种合并方式 \(\Leftrightarrow\) ... 
- 『Exclusive Access 2 dilworth定理 状压dp』
		Exclusive Access 2 Description 给出 N 个点M 条边的无向图,定向得到有向无环图,使得最长路最短. N ≤ 15, M ≤ 100 Input Format 第一行一个 ... 
- CF1103D Codeforces Round #534 (Div. 1) Professional layer   状压 DP
		题目传送门 https://codeforces.com/contest/1103/problem/D 题解 失去信仰的低水平选手的看题解的心路历程. 一开始看题目以为是选出一些数,每个数可以除掉一个 ... 
- bzoj4903 & loj2264 [Ctsc2017]吉夫特  Lucas 定理+状压DP
		题目传送门 https://lydsy.com/JudgeOnline/problem.php?id=4903 https://loj.ac/problem/2264 http://uoj.ac/pr ... 
- Codeforces 279D The Minimum Number of Variables 状压dp
		The Minimum Number of Variables 我们定义dp[ i ][ mask ]表示是否存在 处理完前 i 个a, b中存者 a存在的状态是mask 的情况. 然后用sosdp处 ... 
- codeforces#580 D. Kefa and Dishes(状压dp)
		题意:有n个菜,每个菜有个兴奋值,并且如果吃饭第i个菜立即吃第j个菜,那么兴奋值加ma[i][j],求吃m个菜的最大兴奋值,(n<=18) 分析:定义dp[status][last],statu ... 
- Codeforces Round #585 (Div. 2) E. Marbles(状压dp)
		题意:给你一个长度为n的序列 问你需要多少次两两交换 可以让相同的数字在一个区间段 思路:我们可以预处理一个数组cnt[i][j]表示把i放到j前面需要交换多少次 然后二进制枚举后 每次选择一个为1的 ... 
随机推荐
- 程序包 javax.servlet 不存在 解决办法
			其原因是java编译器没有找到软件包javax.servlet. 下载servlet.jar放到lib下没有效果,后发现需要在jdk中添加,如下: 解决办法: 从tomcat lib目录下拷贝一个se ... 
- jquery插件2
			1.很全,好用的jquery插件库:http://www.jq22.com/ 2.素材:http://www.sucaijiayuan.com/ 3.不错:http://www.helloweba.c ... 
- 1 了解Scala
			1 定义变量 单个变量:var name = "benxintuzi" 等价于 var name : String = "benxintuzi"(即定义变量时 ... 
- POJ 1113 Wall【凸包周长】
			题目: http://poj.org/problem?id=1113 http://acm.hust.edu.cn/vjudge/contest/view.action?cid=22013#probl ... 
- DNN优势
- 2017-2018-1 20179209《Linux内核原理与分析》第九周作业
			理解进程调度时机 进程调度时机 中断处理过程(包括时钟中断.I/O中断.系统调用和异常)中,直接调用schedule(),或者返回用户态时根据need_resched标记调用schedule(): 内 ... 
- 【译】Stackoverflow:Java Servlet 工作原理问答
			导读 本文来自stackoverflow的问答,讨论了Java Servlet的工作机制,如何进行实例化.共享变量和多线程处理. 问题:Servlet 是如何工作的?Servlet 如何实例化.共享变 ... 
- http 长连接 & 短连接
			1.意义 同一个TCP连接来发送和接收多个HTTP请求/应答,而不是为每一个新的请求/应答打开新的连接的方法. 2.优 较少的CPU和内存的使用 允许请求和应答的HTTP pipelining 降低网 ... 
- Swift学习 --- 2.1基础部分
			1.swift 能够省去; 2.println与print的差别就是一个能够换行一个不能够 3.swift省去了.h与.m 直接一个swift文件 4.元组能够返回多个值,元组(tuples)把多个值 ... 
- 安装了包,pycharm却提示找不到包
			这段时间,我爬虫爬到了一个论坛的数据,有个分析需要知道他的字符编码,因此使用到了 chardet,我在终端很顺利的安装了这个,但是在pycharm里使用的时候老是提示有错误,向下面这样: 其实这个是因 ... 
