题意

给定一个未知的\(0/1\)矩阵,对每个\(i\)求\((1,1)\sim(n,m)\)最短路为\(i\)的概率,在矩阵中不能向左走,路径长度为路径上权值为\(1\)的格子个数。

\(n\leq6,m\leq100。\)

思路

打死都不可能想到状态设计DP系列

参考了这篇博客的思路【51nod1683】最短路


概率乘了\(2^{n\times m}\)之后其实就是方案数,所以问题转化为了求满足题目条件的方案数

发现\(n\)很小,最大只有\(6\),考虑状压,但是不能直接维护当前格子的最短路,因为在多条并列最短路时会重复计数

考虑现在的\(0/1\)矩阵的特殊性:因为不能向左走,所以对于同一列中相邻两个格子之间的最短路最多相差\(1\)。因此考虑维护一整列最短路的差分数组。

记\(zt\)为一个三进制状态,表示该行从第二行开始,每个格子与上面的格子的差

设\(f[i][j][zt]\)表示第\(i\)列,第一行的最短路为\(j\),第\(2\)行~第\(n\)行的最短路的三进制为\(zt\)的方案数

转移时需要枚举下一列的\(0/1\)状态,线性更新一遍状态就可以了

时间复杂度为\(O(nm2^n3^{n-1})\)

代码

/*
Author:loceaner
*/
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
#define int long long
using namespace std; const int A = 111;
const int B = 1e6 + 11;
const int inf = 0x3f3f3f3f; inline int read() {
char c = getchar();
int x = 0, f = 1;
for (; !isdigit(c); c = getchar()) if (c == '-') f = -1;
for (; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
return x * f;
} int zt[7], d[7], r[7], w[7], qwq, ans[A];
int n, m, mod, f[A][A][A << 3], g[A << 3][1 << 6][2]; signed main() {
n = read(), m = read(), mod = read();
qwq = (1 << n) - 1, zt[0] = 1;
for (int i = 1; i <= n; i++) zt[i] = zt[i - 1] * 3;
for (int s1 = 0; s1 <= zt[n - 1] - 1; s1++) {
d[1] = 0;
for (int i = 1; i <= n - 1; i++) d[i + 1] = d[i] + (s1 / zt[i - 1] % 3 - 1);
for (int s2 = 0; s2 <= qwq; s2++) {
for (int i = 1; i <= n; i++) w[i] = ((s2 & (1 << i - 1)) > 0), r[i] = d[i] + w[i];
for (int i = 2; i <= n; i++) r[i] = min(r[i], r[i - 1] + w[i]);
for (int i = n - 1; i >= 1; i--) r[i] = min(r[i], r[i + 1] + w[i]);
g[s1][s2][0] = r[1];
for (int i = 2; i <= n; i++) g[s1][s2][1] += (r[i] - r[i - 1] + 1) * zt[i - 2];
}
}
memset(d, 0, sizeof(d));
for (int s = 0; s <= qwq; s++) {
for (int i = 1; i <= n; i++) d[i] = d[i - 1] + ((s & (1 << i - 1)) > 0);
int t = 0;
for (int i = 2; i <= n; i++) t += (d[i] - d[i - 1] + 1) * zt[i - 2];
f[1][d[1]][t]++;
}
for (int i = 1; i <= m - 1; i++)
for (int j = 0; j <= i; j++)
for (int s = 0; s <= zt[n - 1] - 1; s++) {
if (!f[i][j][s]) continue;
for (int x = 0; x <= (1 << n) - 1; x++)
(f[i + 1][g[s][x][0] + j][g[s][x][1]] += f[i][j][s]) %= mod;
}
for (int j = 0; j <= m; j++)
for (int s = 0; s <= zt[n - 1] - 1; s++) {
if (!f[m][j][s])
continue;
d[1] = j;
for (int i = 1; i <= n - 1; i++) d[i + 1] = d[i] + (s / zt[i - 1] % 3 - 1);
if (d[n] < 0) continue;
(ans[d[n]] += f[m][j][s]) %= mod;
}
for (int i = 0; i <= n + m - 1; i++) cout << ans[i] << '\n';
return 0;
}

51Nod 1683 最短路的更多相关文章

  1. 51-nod(1443)(最短路)

    解题思路:最短路+记录前驱和,刚开始一直以为是最短路+MST,结果发现,因为无向图的原因,有些边权很小的边再最短路处理后可能这条边也符合某两个点的最短路径,所以我们觉得这条边也是可以在MST处理中使用 ...

  2. DP没入门就入土

    写在前面 记录最近刷的DP题 以及 打死都不可能想到状态设计DP系列 汇总 洛谷 P6082 [JSOI2015]salesman 树形\(\texttt{DP}\) + 优先队列 比较容易看出来这是 ...

  3. 51nod 1445 变色DNA(最短路变形)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1445 题意: 思路: 挺好的一道题目,如果$colormap[i][j] ...

  4. 51nod 1443 路径和树(最短路)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1443 1443 路径和树 题目来源: CodeForces ...

  5. 51nod 1443 路径和树——最短路生成树

    题目:http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1443 不只是做一遍最短路.还要在可以选的边里选最短的才行. 以为是 ...

  6. 51nod 1693 水群(神奇的最短路!)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1693 题意: 思路: 这个思路真是神了.. 对于每个点$i$,它需要和$ ...

  7. 51nod 1444 破坏道路(最短路)

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1444 题意: 思路: 哇,思路爆炸. 因为每条边的权值都为1,所以可以直 ...

  8. 51nod 1649.齐头并进-最短路(Dijkstra)

    1649 齐头并进 题目来源: CodeForces 基准时间限制:1 秒 空间限制:131072 KB 分值: 10 难度:2级算法题 在一个叫奥斯汀的城市,有n个小镇(从1到n编号),这些小镇通过 ...

  9. 51nod 1445:变色DNA 最短路变形

    1445 变色DNA 题目来源: TopCoder 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题  收藏  关注 有一只特别的狼,它在每个夜晚会进行变色,研究发现 ...

随机推荐

  1. java实现第五届蓝桥杯圆周率

    圆周率 数学发展历史上,圆周率的计算曾有许多有趣甚至是传奇的故事.其中许多方法都涉及无穷级数. 图1.png中所示,就是一种用连分数的形式表示的圆周率求法. 下面的程序实现了该求解方法.实际上数列的收 ...

  2. 使用Json框架解析遇到Java关键字时的解决方案

    当Json数据中的key为Java关键字时,在定义实体类的时候不能对该字段进行声明,所以需要对字段进行特殊处理 使用Gson解析 在与Java关键字冲突的字段加上@SerializedName注解 @ ...

  3. 括号匹配-算法详细题解LeetCode

    题目:有效的括号 给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效. 有效字符串需满足: 左括号必须用相同类型的右括号闭合. 左括号必须以正确的顺序闭合. ...

  4. IDEA自定义模板

    RT,虽然看起来简单,每当配置新的IDEA 时,又不免度娘,所以整理下 1.类的模板 路径: settings-Editor-File and Code Templates 右侧找到 class 添加 ...

  5. 🧑🏻‍💻数据库简介及Mac平台环境搭建🧑🏻‍💻

    数据库 存储数据的演变过程 如果没有使用数据库,我们自己存放文件,数据格式是千差万别的,完全取决于我们自己,例如: """ # 张三 zhangsan|123|read ...

  6. 如何安装 Sublime text 编辑器相关的插件

    Sublime是一个伟大的编辑器,具有可靠的基础功能,使编写代码变得愉快.您可以安装一个包管理器,以便于安装插件和添加新功能. 为什么使用包管理器(package manager) 包管理器可以方便地 ...

  7. Nice Jquery Validator 内置属性

    required - 必填 适用于 input.textarea.select 输入框.(checkbox 与 radio 请使用 checked 规则)字段必填,则值不能为空.字段非必填,则值为空的 ...

  8. Chosen by god【组合数打表】

    Chosen by god 题目链接(点击) Everyone knows there is a computer game names "hearth stone", recen ...

  9. 关于单向循环链表的约瑟夫问题(Java实现)

    关于单向循环链表的约瑟夫问题(Java实现) 最近在学习链表时,遇到单向循环链表中的约瑟夫问题.在构建循环链表的代码上,我有一点很不理解,遂记录下来. Josephu问题为: 设编号为1, 2,.. ...

  10. cb36a_c++_STL_算法_区间的比较equal_mismatch_lexicographical_compare

    *cb36a_c++_STL_算法_区间的比较equal_mismatch_lexicographical_compare 区间:容器中的全部数据或者部分数据,都叫做区间 equal(b,e,b2), ...