[tsinsen_A1278]串珠子

试题描述

铭铭有 \(n\) 个十分漂亮的珠子和若干根颜色不同的绳子。现在铭铭想用绳子把所有的珠子连接成一个整体。

现在已知所有珠子互不相同,用整数 \(1\) 到 \(n\) 编号。对于第 \(i\) 个珠子和第 \(j\) 个珠子,可以选择不用绳子连接,或者在 \(c_{i,j}\) 根不同颜色的绳子中选择一根将它们连接。如果把珠子看作点,把绳子看作边,将所有珠子连成一个整体即为所有点构成一个连通图。特别地,珠子不能和自己连接。

铭铭希望知道总共有多少种不同的方案将所有珠子连成一个整体。由于答案可能很大,因此只需输出答案对 \(1000000007\) 取模的结果。

输入

标准输入。输入第一行包含一个正整数 \(n\),表示珠子的个数。接下来 \(n\) 行,每行包含 \(n\) 个非负整数,用空格隔开。这 \(n\) 行中,第 \(i\) 行第 \(j\) 个数为 \(c_{i,j}\)。

输出

标准输出。输出一行一个整数,为连接方案数对 \(1000000007\) 取模的结果。

输入示例

3
0 2 3
2 0 4
3 4 0

输出示例

50

数据规模及约定

对于 \(100\%\) 的数据,\(n\) 为正整数,所有的 \(c_{i,j}\) 为非负整数且不超过 \(1000000007\)。保证 \(c_{i,j}=c_{j,i}\)。每组数据的 \(n\) 值如下表所示。

编号 1 2 3 4 5 6 7 8 9 10
$n$ $8$ $9$ $9$ $10$ $11$ $12$ $13$ $14$ $15$ $16$

题解

一道挺经典的状压 dp,这题有一些计数技巧。

状态很简单,就是令 \(f(s)\) 表示集合 \(s\) 内所有点处于一个连通分量内的方案数,关键是怎么转移。

为了让计算的方案不重不漏,我们需要设计一个方案使得每次转移都是唯一的,不会被重复转移,同时也能够让转移覆盖到所有情况。

这题就是找到集合 \(s\) 中的前两个元素(或者第一个和最后一个元素也行,需要保证每次都选的是特定的两个元素),令第一个为 \(t_1\),第二个为 \(t_2\),然后我们要枚举第一次拆解(这次拆解后的两个集合都通过 \(t_1\) 这个点相连,即 \(t_1\) 是 \(s\) 连通分量的割顶),并且由于这个拆解是没有顺序的,所以我们要保证每次拆解都需要将 \(t_1\) 和 \(t_2\) 分开。于是枚举 \(s\) 的子集 \(s'\),使得 \(t_2 \in s'\) 且 \(t_1 \in s - s'\),然后将 \(s\) 分成 \(s'\) 和 \(s - s'\) 两个集合,最后转移就是 \(f(s) = f(s') \cdot f(s-s') \cdot \prod_{i \in s'} {c_{t_1, i}}\)。

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <algorithm>
using namespace std;
#define rep(i, s, t) for(int i = (s); i <= (t); i++)
#define dwn(i, s, t) for(int i = (s); i >= (t); i--)const int BufferSize = 1 << 16;
char buffer[BufferSize], *Head, *Tail;
inline char Getchar() {if(Head == Tail) {int l = fread(buffer, 1, BufferSize, stdin);Tail = (Head = buffer) + l;}return *Head++;
}
int read() {int x = 0, f = 1; char c = Getchar();while(!isdigit(c)){ if(c == '-') f = -1; c = Getchar(); }while(isdigit(c)){ x = x * 10 + c - '0'; c = Getchar(); }return x * f;
}#define maxn 20
#define maxs 65536
#define MOD 1000000007
#define LL long longint n, c[maxn][maxn], Log[maxs], f[maxs], mul[maxn][maxs];int main() {n = read();rep(i, 0, n - 1) rep(j, 0, n - 1) c[i][j] = read();int all = (1 << n) - 1;Log[1] = 0;rep(i, 2, all + 1) Log[i] = Log[i>>1] + 1;rep(i, 0, n - 1) {mul[i][0] = 1;rep(s, 1, all) mul[i][s] = (LL)mul[i][s&~(s&-s)] * (c[i][Log[s&-s]] + 1) % MOD;}rep(s, 1, all) {int cnt = 0, t1 = -1, t2 = -1;rep(i, 0, n - 1) if(s >> i & 1) {cnt++;if(t1 < 0) t1 = i;else if(t2 < 0) t2 = i;}if(cnt == 1){ f[s] = 1; continue; }for(int ts = (s - 1 & s); ts; ts = (ts - 1 & s)) if((ts >> t2 & 1) && !(ts >> t1 & 1)) {f[s] += (LL)f[ts] * f[s^ts] % MOD * (mul[t1][ts] + MOD - 1) % MOD;if(f[s] >= MOD) f[s] -= MOD;}}printf("%d\n", f[all]);return 0;
}

转载于:https://www.cnblogs.com/xiao-ju-ruo-xjr/p/7998910.html

[tsinsen_A1278]串珠子相关推荐

  1. bzoj2560串珠子 状压dp+容斥(?)

    2560: 串珠子 Time Limit: 10 Sec  Memory Limit: 128 MB Submit: 515  Solved: 348 [Submit][Status][Discuss ...

  2. BZOJ2560 串珠子

    2560: 串珠子 Time Limit: 10 Sec   Memory Limit: 128 MB Submit: 469   Solved: 313 [ Submit][ Status][ Di ...

  3. [bzoj2560] 串珠子

    [bzoj2560] 串珠子 我的状压dp大概是废掉了 这道题考虑容斥,然后g[i]记总方案,f[i]记答案 然后我们枚举子集 j ,f [ i ] = f [ i ] - sigma { f [ i ...

  4. BZOJ 2560: 串珠子 (状压DP+枚举子集补集+容斥)

    (Noip提高组及以下),有意者请联系Lydsy2012@163.com,仅限教师及家长用户. 2560: 串珠子 Time Limit: 10 Sec Memory Limit: 128 MB Su ...

  5. uva10054--欧拉回路--串珠子

    题意: 给出不同颜色的珠子,珠子的两边有两种颜色,串珠子时相邻的珠子颜色要相同.比如12就可以接在32的后面,注意最后一颗珠子要和第一颗珠子要连在一起,也就是说要形成一个回路. 思路: 无脑dfs,因 ...

  6. [清华集训2012]串珠子

    题目链接:[清华集训2012]串珠子 因为得到的是一个连通图,所以我们可以考虑用任意连边的方案数减去不连通的方案数. 对于不连通的方案数,我们可以让一个子集连通,然后另一个子集随意连边.但是这样子集转 ...

  7. P5933 [清华集训2012]串珠子(连通性 状压 计数)

    P5933 [清华集训2012]串珠子 \(\color{yellow}{\bigstar\texttt{Trick}}\):遇到连通性题可以暂时忽略是否联通. 设 \(g_s\) 表示集合为 \(s ...

  8. python练习:求一串珠子中包含所有颜色最短的一串长度

    题目 某年 百度的面试题. 一串首尾相连的珠子有 m 个,共有 N 种颜色(N <= 10).设计一个算法,取出其中一段,要求包含所有 N 种颜色,并且长度最短. 思路 使用一个额外的数组 fl ...

  9. bzoj 2560: 串珠子

    题意: 铭铭有n个十分漂亮的珠子和若干根颜色不同的绳子.现在铭铭想用绳子把所有的珠子连接成一个整体. 现在已知所有珠子互不相同,用整数1到n编号.对于第i个珠子和第j个珠子,可以选择不用绳子连接,或者 ...

最新文章

  1. 人工智能的恶意用途:预测、预防和缓解
  2. Consumer is not subscribed to any topics
  3. Java多线程两种实现方式的对比
  4. css应用网页设计,CSS技术在网页设计中的运用
  5. java外挂源码_2.7 万 Star!Github 项目源码辅助阅读神器
  6. PHP写猜数字,PHP算法之猜数字
  7. UEditor在线编辑器配置及注意事项
  8. 详解 undefined 与 null 的区别
  9. WindowsBuilder控件中文编码问题
  10. 脑电时频分析II:时频分析
  11. 获取b站网页html5,教给你4种方法下B站视频,得到真实地址的方法
  12. 语句覆盖、判定覆盖、条件覆盖、路径覆盖
  13. office2013 vol版本
  14. SSDAlloc:用 SSD 扩展内存
  15. C++计算耗时方法(四种方法)
  16. MySQL表查询关键字
  17. 使用Python将OV7725的RGB565图像数据转换为jpg图像
  18. ChatGPT自动写了个AI办公office word插件,低配copilot,程序员看了焦虑。
  19. 最新的IP归属地数据库-最新IP地址数据库
  20. Ubuntu 搜狗输入法无法调出问题解决备忘

热门文章

  1. 第02章 Unicode简介
  2. AE(Aeternity)项目分析
  3. matlab计算膜孔径分布,应用Matlab绘制活性炭吸附等温线和孔径分布图
  4. 钱旺之行:互联网经济的增长点——注意力价值经济
  5. 参加技术校园招聘,你最好先了解这五件事
  6. php文件怎么改为mp3,[视频转音频软件]怎么把mp4转换成mp3音乐格式
  7. mac M1 mysql workbench 打开table闪退
  8. 基于粒子群优化算法的无人机路径规划与轨迹算法的实现(Matlab代码实现)
  9. Java修炼之凡界篇 筑基期 第05卷 数组 第06话 Arrays 类
  10. Jenkins怎么发邮件,高级测试手把手教你...