闻所未闻的$dp$神题(我不会的题)

令$f[S][i]$表示子集状态为$S$,且$S$中最大联通块恰好为$i$的方案数

考虑转移,我们枚举$S$中最小的元素$v$来转移,这样就能不重

$f[S][i] = \sum\limits_{T \in S \;and\;v \in T} f[T][...] * C[S \wedge T]$

由于这么递归转移不好确定后面的状态,因此我们可以递推转移,在代码中有所体现

$C[S]$表示将$S$联通的方案数

我们考虑容斥,用全集减去所有不联通的方案数,我们考虑枚举最小点$v$所在的集合

之后转移时$C[S] = 2^{E[S]} - \sum\limits_{T \in s \;ans\;v\; \in T} C[T] * 2^{E[S \wedge T]}$

其中,$E[S]$表示处于$S$内部的边的方案数

复杂度$O(3^n * n)$

#include <set>
#include <vector>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
namespace remoon {
#define re register
#define de double
#define le long double
#define ri register int
#define ll long long
#define sh short
#define pii pair<int, int>
#define mp make_pair
#define pb push_back
#define fi first
#define se second
#define tpr template <typename ra>
#define rep(iu, st, ed) for(ri iu = st; iu <= ed; iu ++)
#define drep(iu, ed, st) for(ri iu = ed; iu >= st; iu --)
#define gc getchar
inline int read() {
int p = , w = ; char c = gc();
while(c > '' || c < '') { if(c == '-') w = -; c = gc(); }
while(c >= '' && c <= '') p = p * + c - '', c = gc(); return p * w;
}
int wr[], rw;
#define pc(iw) putchar(iw)
tpr inline void write(ra o, char c = '\n') {
if(!o) pc('');
if(o < ) o = -o, pc('-');
while(o) wr[++ rw] = o % , o /= ;
while(rw) pc(wr[rw --] + '');
pc(c);
}
tpr inline void cmin(ra &a, ra b) { if(a > b) a = b; }
tpr inline void cmax(ra &a, ra b) { if(a < b) a = b; }
tpr inline bool ckmin(ra &a, ra b) { return (a > b) ? a = b, : ; }
tpr inline bool ckmax(ra &a, ra b) { return (a < b) ? a = b, : ; }
}
using namespace std;
using namespace remoon; #define sid 17
#define mod 1000000007 inline void inc(int &a, int b) { a += b; if(a >= mod) a -= mod; }
inline void dec(int &a, int b) { a -= b; if(a < ) a += mod; }
inline int mul(int a, int b) { return 1ll * a * b % mod; } int pc[];
int u[], v[];
int E[( << ) + ], C[( << ) + ];
int f[( << ) + ][sid];
int n, m; int main() { n = read(); m = read(); pc[] = ;
rep(i, , ) pc[i] = mul(pc[i - ], );
rep(i, , m) u[i] = read(), v[i] = read(); rep(S, , ( << n) - ) rep(i, , m)
if((S & ( << u[i] - )) && (S & ( << v[i] - ))) ++ E[S]; C[] = ;
rep(S, , ( << n) - ) {
int res = pc[E[S]], mi = -;
rep(i, , n) if(S & ( << i - )) { mi = i; break; }
for(ri T = S & (S - ); T; T = (T - ) & S)
if(T & ( << mi - )) dec(res, mul(C[T], pc[E[S ^ T]]));
C[S] = res;
} f[][] = ;
rep(S, , ( << n) - ) rep(j, , n) if(f[S][j]) {
int mi = -;
rep(i, , n) if(!(S & ( << i - ))) { mi = i; break; }
if(mi == -) continue;
int D = (( << n) - ) ^ (S | ( << mi - ));
for(ri T = D; ; T = (T - ) & D) {
int st = __builtin_popcount(T | ( << mi - ));
inc(f[S | ( << mi - ) | T][max(j, st)], mul(f[S][j], C[( << mi - ) | T]));
if(!T) break;
}
} rep(i, , n)
write(f[( << n) - ][i]); return ;
}

hihocoder #1071 : 小玩具的更多相关文章

  1. C#监控类属性的更改(大花猫动了哪些小玩具)

    C#监控类属性的更改(大花猫动了哪些小玩具) 实体类创建后在方法中对哪些属性赋值了,传递到底层方法时在底层如何得知哪些属性被赋值过.如何监控属性的更改,请看脑洞大开之<大花猫动了哪些小玩具> ...

  2. hihocoder#1513 : 小Hi的烦恼 bitset

    目录 题目链接 题解 代码 题目链接 hihocoder#1513 : 小Hi的烦恼 题解 cdq 套cdq 套cdq 套cdq就完了呀 对每一科开n个bitset 表示该科目前i个有谁 每次查询都& ...

  3. hihoCoder 1513 小Hi的烦恼

    hihoCoder 1513 小Hi的烦恼 思路: 用bitset判断交集个数 代码: #include<bits/stdc++.h> using namespace std; #defi ...

  4. HihoCoder 1473 : 小Ho的强迫症( 欧几里得 )

    描述 小Ho在一条笔直的街道上散步.街道上铺着长度为L的石板,所以每隔L距离就有一条石板连接的缝隙,如下图所示. 小Ho在散步的时候有奇怪的强迫症,他不希望脚踩在石板的缝隙上.(如果小Ho一只脚的脚尖 ...

  5. hihocoder 1347 小h的树上的朋友

    传送门 时间限制:18000ms单点时限:2000ms内存限制:512MB 描述 小h拥有$n$位朋友.每位朋友拥有一个数值$V_i$代表他与小h的亲密度.亲密度有可能发生变化.岁月流逝,小h的朋友们 ...

  6. JavaScript实现图片裁剪预览效果~(第一个小玩具)

    感觉开始学习的前一个月真的太不珍惜慕课网的资源了  上面蛮多小玩意真的蛮适合我这样刚入门JavaScript的同学加深使用理解 大概收藏了百来门或大或小的课程  有一个感觉就是学这个真的比光是看书看概 ...

  7. hihocoder 1513 小Hi的烦恼——bitset

    题目:http://hihocoder.com/problemset/problem/1513 自带的题解写得很好…… #include<cstdio> #include<cstri ...

  8. python kmeans实战 - 单机一层聚类(小玩具哦),下次再弄个分布式多次聚类

    # coding=utf-8     """   #K-means   """          import time           ...

  9. HihoCoder 1638 : 小Hi的天平 (2-sat+并查集)

    描述 小Hi给小Ho邮寄了一个天平.收到天平后,小Ho想知道天平在运输过程中是否损坏,为此它准备了A类物品和B类物品共n个(可能只有A类物品,也可能只有B类物品),但无法确定一个物品是哪一类.A类物品 ...

随机推荐

  1. WPF:ComboBox使用XmlDataProvider做级联

    程序功能: 使用ComboBox做级联,数据源为XML文件,适合小数据量呈现 程序代码: <Window x:Class="WpfApplication1.LayouTest" ...

  2. 【洛谷 P1502】 窗口的星星(扫描线)

    题目链接 把每个星星作为左下角,做出长为\(w-0.5\),宽为\(h-0.5\)的矩形. \(-0.5\)是因为边框上的不算. 离散化\(y\)坐标. 记录\(2n\)个\(4\)元组\((x,y1 ...

  3. 天梯赛 L1-006 连续因子 (模拟)

    一个正整数N的因子中可能存在若干连续的数字.例如630可以分解为356*7,其中5.6.7就是3个连续的数字.给定任一正整数N,要求编写程序求出最长连续因子的个数,并输出最小的连续因子序列. 输入格式 ...

  4. 41、用Python实现一个二分查找的函数

    data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35] def binary_search(dataset ...

  5. c语言学习笔记.内存管理.

    内存: 每个程序的内存是分区的:堆区.栈区.静态区.代码区. 1.代码区:放置所有的可执行代码,包括main函数. 2.静态区:存放所有的全局变量和静态变量. 3.栈区:栈(stack),先进后出.存 ...

  6. MySQL删除数据几种情况以及是否释放磁盘空间【转】

    MySQL删除数据几种情况以及是否释放磁盘空间: 1.drop table table_name 立刻释放磁盘空间 ,不管是 Innodb和MyISAM ; 2.truncate table tabl ...

  7. BZOJ - Problem 3622 - 已经没有什么好害怕的了

    题意: 给定两个序列$a$和$b$,让它们进行匹配,求出使得$a_i > b_j$的个数比$a_i < b_j$的个数恰好多$k$,求这样的匹配方法数 题解: 这题的各种表示有一点相似又截 ...

  8. 微信开发,调用js-SDK接口

    微信开发,调用js-SDK接口<!DOCTYPE html><html><head lang="en"> <meta charset=&q ...

  9. #include<stdarg.h> 可变参数使用

    今天上计算方法这课时觉得无聊至极,于是拿出C++编程之道来看了看..无意之中看到了#include<stdarg.h> va_list,va_start,va_end等东西,不知是怎么用的 ...

  10. 重置HTML标签样式

    ;;} header,footer,section,article,aside,nav,hgroup,address,figure,figcaption,menu,details{display:bl ...