【bfs分层图 dp】hihocoder#1147 : 时空阵
最短路径树上分层dp的一类套路吧
题目大意
幽香这几天学习了魔法,准备建造一个大型的时空传送阵。
幽香现在可以在幻想乡的n个地点建造一些传送门,如果她建造了从地点a与地点b之间的传送门,那么从a到b和从b到a都只需要单位1的时间。
同时这些地点之间在地理上是非常遥远的,因此来往他们必须使用传送门。
现在幽香想要问你,有多少种建造传送门的方案,使得地点1和地点n之间的最短距离恰好为k?两个方案不同当且仅当建造的传送门的集合不同。不能建造节点到自身的传送门,两个点之间也最多造一个传送门。
$n,k \le 100$
题目分析
特殊性质在于每条边长度都为1,这点让人联想到bfs;而看到最短路则自然想起最短路径树。
那么我们就考虑按照bfs序dp这张图的最短路径树,也就是分层往下dp。在分层dp的树中,跨层的点不能连边;邻层及同层的点可以随意连边,最终目标是把$n$号点安排在$k+1$层,如果还有剩下的点则接下去随意安排。
不过这里有一种省去分类讨论的小trick:我们不计标号地计算剩下$n-1$个点的方案数,而由于这$n-1$个点是完全等价的,相当于最后再把总方案数乘以$(n-1)^{-1}$即可。
用$f_{i,t,l}$表示构造了$i$层,总共使用了$t$个节点(包括1号点),当前层有$l$个节点的方案数。转移时枚举上一层有$p$个节点。边界条件$f_{1,1,1}=1$

大致形状如上所示。
考虑p到l的转移:首先从$n-(t-l)$个点中取出$l$个点,取出的每个点向$p$个点连边有$2^p-1$种方案;$l$个点同层连边有$2^{l\choose 2}$种方案。
最后再枚举所有情况统计一趟即可。
#include<bits/stdc++.h>
#define MO 1000000007
typedef long long ll;
const int maxn = ; int n,k,fac[maxn],facinv[maxn],mi[maxn];
ll f[maxn][maxn][maxn],ans; int qmi(ll a, ll b)
{
int ret = ;
for (a%=MO; b; b>>=,a=1ll*a*a%MO)
if (b&) ret = 1ll*ret*a%MO;
return ret;
}
int C(int n, int m)
{
if (n < m) return ;
return 1ll*fac[n]*facinv[n-m]%MO*facinv[m]%MO;
}
int main()
{
scanf("%d%d",&n,&k);
facinv[] = facinv[] = fac[] = mi[] = ;
for (int i=; i<=; i++)
facinv[i] = MO-1ll*MO/i*facinv[MO%i]%MO;
for (int i=; i<=; i++)
mi[i] = 2ll*mi[i-]%MO, fac[i] = 1ll*fac[i-]*i%MO, facinv[i] = 1ll*facinv[i-]*facinv[i]%MO;
f[][][] = ;
for (int i=; i<=k+; i++)
for (int t=i; t<=n; t++)
for (int l=; l<=t-i+; l++)
for (int p=; p<=t-l-i+; p++)
f[i][t][l] = (f[i][t][l]+1ll*f[i-][t-l][p]*qmi(mi[p]-, l)%MO*C(n-t+l, l)%MO*qmi(, C(l, ))%MO)%MO;
for (int i=; i<=n; i++)
for (int j=; j<=n; j++)
if (f[k+][i][j])
ans = (ans+1ll*f[k+][i][j]*j%MO*qmi(, C(n-i, ))%MO*qmi(, 1ll*j*(n-i)%MO))%MO;
printf("%lld\n",1ll*ans*qmi(n-, MO-)%MO);
return ;
}
END
【bfs分层图 dp】hihocoder#1147 : 时空阵的更多相关文章
- BZOJ_1195_[HNOI2006]最短母串_AC自动机+BFS+分层图
BZOJ_1195_[HNOI2006]最短母串_AC自动机+BFS+分层图 Description 给定n个字符串(S1,S2,„,Sn),要求找到一个最短的字符串T,使得这n个字符串(S1,S2, ...
- codeforces 677D(分层图dp)
Codeforces 677D 传送门:https://codeforces.com/contest/677/problem/D 题意: 给你一个n*m的方格图,每个点有一个权值val,现在要求你从坐 ...
- 「hdu 4845 」拯救大兵瑞恩 [CTSC 1999](状态压缩bfs & 分层图思想)
首先关于分层图思想详见2004的这个论文 https://wenku.baidu.com/view/dc57f205cc175527072208ad.html 这道题可以用状态压缩,我们对于每一把钥匙 ...
- POJ3635 Full Tank? 优先队列BFS or 分层图最短路 or DP?
然而我也不知道这是啥啊...反正差不多...哪位大佬给区分一下QWQ.. 好的,我把堆的<写反了..又调了一个小时..你能不能稳一点.... 记录状态:所在位置u,油量c,花费w 扩展状态: 1 ...
- POJ 3635 Full Tank? 【分层图/最短路dp】
任意门:http://poj.org/problem?id=3635 Full Tank? Time Limit: 1000MS Memory Limit: 65536K Total Submis ...
- BZOJ_1916_[Usaco2010 Open]冲浪_分层图+拓扑排序+DP
BZOJ_1916_[Usaco2010 Open]冲浪_分层图+拓扑排序+DP Description 受到秘鲁的马丘比丘的新式水上乐园的启发,Farmer John决定也为奶牛们建 一个水上乐园. ...
- [luogu1073 Noip2009] 最优贸易 (dp || SPFA+分层图)
传送门 Description C 国有n 个大城市和m 条道路,每条道路连接这n 个城市中的某两个城市.任意两个 城市之间最多只有一条道路直接相连.这m 条道路中有一部分为单向通行的道路,一部分 为 ...
- 线性dp,分层图思想
题目大意:给你一串数字,一串运算符,求递推用完运算符时答案的最大值----->线性dp dp[i][j] i表示所用数字的个数 j表示所用字符的个数 分层图思想 所有字符必须用完 所以取最后 ...
- 一本通 高手训练 1782 分层图 状压dp
LINK:分层图 很精辟的一道题 写的时候没带脑子 导致搞了半天不知道哪错了. 可以想到状压每次到某一层的状态 然后这个表示方案数 多开一维表示此时路径条数的奇偶即可. 不过显然我们只需要知道路径条数 ...
随机推荐
- Kali基础
1.Kali Linux 2.0 发布下载,基于 Debian 的 Linux 发行版 http://www.linuxidc.com/Linux/2015-08/121549.htm 2. Kal ...
- Redis内存分析工具—redis-rdb-tools (转载http://www.voidcn.com/article/p-axfdqxmd-bro.html)
redis-rdb-tools是由Python写的用来分析Redis的rdb快照文件用的工具,它可以把rdb快照文件生成json文件或者生成报表用来分析Redis的使用详情.使用标准的diff工具比较 ...
- Spring Boot CommandLineRunner的使用
1. 说明 程序在启动完成的时候需要去处理某些业务,因此Spring Boot程序中需要去实现CommandLineRunner接口. 2. CommandLineRunner方法执行顺序 程序启动后 ...
- 【LOJ】#3101. 「JSOI2019」精准预测
LOJ#3101. 「JSOI2019」精准预测 设0是生,1是死,按2-sat连边那么第一种情况是\((t,x,1) \rightarrow (t + 1,y,1)\),\((t + 1,y, 0) ...
- SpringBoot以WAR包部署遇到的坑---集合贴
⒈忽略tomcat的context-path 方式一: 停止tomcat服务,删除tomcat安装目录的webapps目录下的ROOT目录,将打成的WAR包重命名为ROOT.war,重启tomcat服 ...
- C#读写操作app.config中的数据
<?xml version="1.0" encoding="utf-8" ?> <configuration> <connecti ...
- (二十三)Dbutils 工具介绍
目录 Dbutils简介 API 介绍 Dbutils 已实现的结果集处理器 : Dbutils简介 commons-dbutis 是Apache 组织提供的一个开源JDBC工具类库,它对JDBC进行 ...
- LC 394. Decode String
问题描述 Given an encoded string, return its decoded string. The encoding rule is: k[encoded_string], wh ...
- Java手写简单Linkedlist一(包括增加,插入,查找,toString,remove功能)
@Java300 学习总结 一.自定义节点 LinkList底层为双向链表.特点为查询效率低,但增删效率高,线程不安全. 链表数据储存在节点,且每个节点有指向上个和下个节点的指针. 创建ggLinke ...
- docker 入门2 - 容器 【翻译】
入门,第 2 部分:容器 先决条件 安装的 Docker 版本是 1.13 及以上. 读完 第一部分 用下面的命令快速测试你的环境是否完备: docker run hello-world 概述 现在开 ...