【BZOJ2576】[JSOI2011]序的计数 (动态规划)
【BZOJ2576】[JSOI2011]序的计数 (动态规划)
题面
题解
首先构建一个新的虚拟节点连接所有目标节点,强行将其作为第一个被访问的节点,这样子就解决了图不连通的问题。
除了目标节点外,所有其他点都可以缩成一个节点。
这样子的图实际上只有\(k+2\)个节点,\(k+1\)个目标节点。
预处理\(G[S][u]\)表示已经在\(dfs\)序中出现过的点的集合为\(S\),当前在点\(u\)能够访问到的点。
设\(f[S][u]\)表示当前在点\(u\),已经确定\(dfs\)序的集合为\(S\)的\(dfs\)序的方案数。
注意如果一个点和不合法的点有连边,那么这个点不能回朔。
转移的时候枚举一个\(u\)的相邻点,记忆化搜索即可。
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
#define ll long long
#define MAX 120
inline int read()
{
int x=0;bool t=false;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=true,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return t?-x:x;
}
int n,m,K,id[MAX],S[20];
bool g[MAX][MAX],M[20][20];
ll f[1<<19][20];
int G[1<<19][20];
int dfs(int u,int S)
{
if(~G[S][u])return G[S][u];
int ret=1<<u;
for(int i=0;i<K;++i)
if(M[u][i]&&!(S&(1<<i)))ret|=dfs(i,S|(1<<i));
return G[S][u]=ret;
}
ll Solve(int u,int S)
{
if(~f[S][u])return f[S][u];
if(G[S][u]==1<<u)return S==(1<<K)-1||!M[u][K];
ll ret=0;
for(int i=0;i<K;++i)
if(M[u][i]&&!(S&(1<<i)))
ret+=Solve(i,S|(1<<i))*Solve(u,S|G[S|(1<<i)][i]);
return f[S][u]=ret;
}
int main()
{
n=read();m=read();K=read();K+=1;
for(int i=1,u,v;i<=m;++i)u=read(),v=read(),g[u][v]=g[v][u]=1;
for(int i=1;i<=n;++i)id[i]=K;
for(int i=0;i<K-1;++i)S[i]=read(),id[S[i]]=i,M[i][K-1]=M[K-1][i]=1;
for(int i=0;i<=K;++i)
for(int j=1;j<=n;++j)M[i][id[j]]|=g[S[i]][j];
memset(G,-1,sizeof(G));memset(f,-1,sizeof(f));
for(int i=0;i<(1<<K);++i)
for(int j=0;j<K;++j)
if(i&(1<<j))dfs(j,i);
printf("%lld\n",Solve(K-1,1<<(K-1)));
return 0;
}
【BZOJ2576】[JSOI2011]序的计数 (动态规划)的更多相关文章
- leetcode-最大子序和(动态规划讲解)
最大子序和(动态规划讲解) 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4], 输 ...
- Leetcode题目53.最大子序和(动态规划-简单)
题目描述: 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和. 示例: 输入: [-2,1,-3,4,-1,2,1,-5,4],输出: 6解释: 连 ...
- UOJ#290. 【ZJOI2017】仙人掌 仙人掌,Tarjan,计数,动态规划,树形dp,递推
原文链接https://www.cnblogs.com/zhouzhendong/p/UOJ290.html 题解 真是一道好题! 首先,如果不是仙人掌直接输出 0 . 否则,显然先把环上的边删光. ...
- bzoj AC倒序
Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...
- Noip前的大抱佛脚----动态规划
目录 动态规划 序列DP 背包问题 状态压缩以及拆分数 期望概率DP 马尔可夫过程 一类生成树计数问题 平方计数 动态规划 序列DP 有些问题: 求长度为\(l\)的上升子序列个数 形如一个值域的前缀 ...
- bzoj1211: [HNOI2004]树的计数 prufer编码
题目链接 bzoj1211: [HNOI2004]树的计数 题解 prufer序 可重排列计数 代码 #include<bits/stdc++.h> using namespace std ...
- 《Cracking the Coding Interview》——第9章:递归和动态规划——题目10
2014-03-20 04:15 题目:你有n个盒子,用这n个盒子堆成一个塔,要求下面的盒子必须在长宽高上都严格大于上面的.如果你不能旋转盒子变换长宽高,这座塔最高能堆多高? 解法:首先将n个盒子按照 ...
- LeetCode初级算法(动态规划+设计问题篇)
目录 爬楼梯 买卖股票的最佳时机 最大子序和 打家劫舍 动态规划小结 Shuffle an Array 最小栈 爬楼梯 第一想法自然是递归,而且爬楼梯很明显是一个斐波拉切数列,所以就有了以下代码: c ...
- 『嗨威说』算法设计与分析 - 动态规划思想小结(HDU 4283 You Are the One)
本文索引目录: 一.动态规划的基本思想 二.数字三角形.最大子段和(PTA)递归方程 三.一道区间动态规划题点拨升华动态规划思想 四.结对编程情况 一.动态规划的基本思想: 1.1 基本概念: 动态规 ...
随机推荐
- Java中JDK和JRE的区别是什么?它们的作用分别是什么?
JDK和JRE是Java开发和运行工具,其中JDK包含了JRE,但是JRE是可以独立安装的,它们在Java开发和运行的时候起到不同的作用~ 1.JDK JDK是Java Development Kit ...
- 硬盘扩容9999T
win+r运行创建命令:subst H: d:\123说明:H指的是想要创建的盘符,d:\123是文件路径 删除命令subst H: d/说明 :H指的是已创建的盘符,/d指的是删除的意思 注意新盘符 ...
- API知识点总结
一.开发api接口开放给其他人调用的api接口(短信接口,支付宝api) 二.api安全弱点数据窃取(解决加密),数据篡改(解决MD5),数据泄露(爬虫技术)(解决令牌)1.加密(HTTPS传输-收费 ...
- 爬虫 之Requests库的详细使用
1.什么是Requests? Requests是用Python语言编写的,基于urllib3来改写的,采用Apache2 Licensed 来源协议的HTTP库. 它比urllib更加方便,可以节约我 ...
- 牛客练习赛13D 幸运数字4
题目链接:https://ac.nowcoder.com/acm/contest/70/D 题目大意: 略 分析: 注意到12! < 10^9 < 13!,于是当n > 13时,第k ...
- Alertmanager 安装(k8s报警)
一.下载Alertmanager https://prometheus.io/download/ wget https://github.com/prometheus/alertmanager/rel ...
- Linux在shell中进入python敲方向键出现「^[[C^[[D」的解决办法
安装yum -y install readline-devel,然后在重新编译python
- JAVA 变量 数据类型 运算符 知识小结
---------------------------------------------------> JAVA 变量 数据类型 运算符 知识小结 <------------------ ...
- Appium之编写H5应用测试脚本(切换到Webview)
App使用H5编写,默认方式找不到元素.启动后获取所有上下文,找到webivew_xxxx的,然后进行切换. 源码: package MyAppium; import io.appium.java_c ...
- Javassist之常用API的应用 02
测试模型代码: package org.study2.JavaSenior.annotation.javassistDemo; /** * @Auther:GongXingRui * @Date:20 ...