落谷Loj

Description

定义机动路径为:

  • 没有自环
  • 路径至少包含两个格子
  • 从起点开始每一步都向不远离终点的方向移动

相同地形序列指路径上顺序经过的地形序列。

定义机动路径的权值为相同地形序列的数量之和。

求所有机动路径的权值之和。

Solution

同一类机动路径,他的贡献就是数量的平方 \(\Leftrightarrow\) 答案即本质不同机动路径数量的平方和 \(\Leftrightarrow\) 即两个人走的机动路径形式相同的方案总和。

由于 从起点开始每一步都向不远离终点的方向移动 这一性质,所以只要我们确定了他移动的 \(x, y\) 方向,那么就可以 \(DP\) 了,因为具有了无后效性。那就枚举一下两个人走的方向。

对于一个人来说,分为左上、左下、右上、右下(一类型)、正上方、正下方、正右方、正左方(二类型)四种状态。

发现一类型包含二类型,所以要简单的容斥一下:

  • 如果两个人都是一类型,那么权值贡献是 \(+\)。

  • 如果两个人 \(1\) 个一类型,\(1\) 个二类型,那么是 \(-\)。

  • 如果两个都是二类型,那么要 \(+\)。

然后当前的 \(f_{a,b,c,d}\) 表示第一个人在 \((a, b)\) ,第二个人在 \((c, d)\)。从起点走到这两个地方的方案数。

把能走的方式处理一下,然后写记搜就行。

复杂度

\(O(64n^2m^2)\)

此题卡常,可以利用 \(work(a, b, c, d) = work(c, d, a, b)\) 的对称性来减小 \(2\) 倍常数

#include <iostream>
#include <cstdio>
#include <cstring>
#define rint register int
using namespace std; const int N = 31, P = 1e9 + 9; int n, m, ans, dx[2][3], dy[2][3], cnt[2], f[N][N][N][N], w[3][3][3][3];
char g[N][N]; int inline dp(int a, int b, int c, int d) {
if (a < 1 || a > n || b < 1 || b > m || c < 1 || c > n || d < 1 || d > m || g[a][b] != g[c][d]) return 0;
if (~f[a][b][c][d]) return f[a][b][c][d];
rint &v = f[a][b][c][d] = 1;
for (rint i = 0; i < cnt[0]; i++)
for (rint j = 0; j < cnt[1]; j++)
(v += dp(a - dx[0][i], b - dy[0][i], c - dx[1][j], d - dy[1][j])) %= P;
return v;
} void prework(int o, int x, int y) {
cnt[o] = 0;
for (int a = -1; a <= 1; a++) {
if (a && a != x) continue;
for (int b = -1; b <= 1; b++) {
if ((b && b != y) || (!a && !b)) continue;
dx[o][cnt[o]] = a, dy[o][cnt[o]] = b, cnt[o]++;
}
}
} int inline work(int a, int b, int c, int d) {
if (~w[a + 1][b + 1][c + 1][d + 1]) return w[a + 1][b + 1][c + 1][d + 1];
prework(0, a, b); prework(1, c, d);
memset(f, -1, sizeof f);
int res = 0;
for (rint i = 1; i <= n; i++)
for (rint j = 1; j <= m; j++)
for (rint k = 1; k <= n; k++)
for (rint l = 1; l <= m; l++) (res += dp(i, j, k, l)) %= P;
w[a + 1][b + 1][c + 1][d + 1] = w[c + 1][d + 1][a + 1][b + 1] = res;
return res;
} int main() {
memset(w, -1, sizeof w);
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; i++) scanf("%s", g[i] + 1);
for (int a = -1; a <= 1; a++) {
for (int b = -1; b <= 1; b++) {
if (!a && !b) continue;
for (int c = -1; c <= 1; c++) {
for (int d = -1; d <= 1; d++) {
if (!c && !d) continue;
if ((a * b && c * d) || (!(a * b) && !(c * d))) (ans += work(a, b, c, d)) %= P;
else ans = (ans - work(a, b, c, d) + P) % P;
}
}
}
}
printf("%d\n", ans);
return 0;
}

BJOI2017 机动训练的更多相关文章

  1. [BZOJ4859][BJOI2017]机动训练(DP)

    4859: [BeiJing2017]机动训练 Time Limit: 20 Sec  Memory Limit: 256 MBSubmit: 105  Solved: 63[Submit][Stat ...

  2. P3713 [BJOI2017]机动训练

    这个题简直神仙,求相同路径的平方就等于两个人走相同路径的方案数.然后...暴力搜索+记忆化就行了,比较玄学. 题干: 题目描述 整个岛可以看作一片 n*m 的区域,每个格子有自己的地形. 一条路径由一 ...

  3. 【LOJ】#2178. 「BJOI2017」机动训练

    题解 遇见平方和就转有序对呗 dp类似从很多点出发每次走一步的转移方式 然后我too naive的,枚举路径长度来决定更新次数,愉快TLE 改成记搜就过了 代码 #include <bits/s ...

  4. bzoj 4859 [BeiJing2017]机动训练

    题面 https://www.lydsy.com/JudgeOnline/problem.php?id=4859 题解 和管道取珠类似 首先把平方转化成两条路径经过的图案相同的方案数 对于一条路径 方 ...

  5. AHOI2018训练日程(3.10~4.12)

    (总计:共90题) 3.10~3.16:17题 3.17~3.23:6题 3.24~3.30:17题 3.31~4.6:21题 4.7~4.12:29题 ZJOI&&FJOI(6题) ...

  6. NOI Online #2 提高组 游记

    没 NOI Online 1 挂的惨就来写游记吧,不知道为啥 NOI Online 1 民间数据测得 60 分的 T1 最后爆零了... 昏昏沉沉的醒来,吃了早饭,等到 \(8:30\) 进入比赛网页 ...

  7. 一个小 Trick

    平方变两次 一个状态 \(S\) 有一个贡献,所有状态 \(S\) 组成集合 \(U\) . 然后我们要统计下面这个东西 \[ans=\sum_{S\in U}f^2(S) \] 然后我们就可以看作是 ...

  8. BJOI做题记录

    BJOI做题记录 终于想起还要做一下历年省选题了2333 然而咕了的还是比做了的多2333 LOJ #2178. 「BJOI2017」机动训练 咕了. LOJ #2179. 「BJOI2017」树的难 ...

  9. SSD框架训练自己的数据集

    SSD demo中详细介绍了如何在VOC数据集上使用SSD进行物体检测的训练和验证.本文介绍如何使用SSD实现对自己数据集的训练和验证过程,内容包括: 1 数据集的标注2 数据集的转换3 使用SSD如 ...

随机推荐

  1. TCP Persist 坚持定时器

    1.坚持定时器在接收方通告接收窗口为0,阻止发送端继续发送数据时设定. 由于连接接收端的发送窗口通告不可靠(只有数据才会确认),如果一个确认丢失了,双方就有可能因为等待对方而使连接终止: 接收放等待接 ...

  2. linux kernel 的 procfs sysfs 对查问题的帮助

    遇到进程卡死,没有gdb 符号表:只能strace 跟踪处理分析 排查过程: 1.ps -aux 查看卡死进程pid 2.strace -T -tt -e trace=all -p 查看卡死进程系统调 ...

  3. rgw实现nfs的首测

    功能介绍 关于rgw实现nfs接口这个,刚接触的人可能并不清楚这个是个什么样的服务架构,rgw是ceph里面的对象存储接口,而nfs则是纯正的网络文件系统接口,这二者如何结合在一起,关于这个,有几个相 ...

  4. WPF控件库总结

    前言 在使用WPF项目的时候, 一般首要的就是对UI部分的选型, 而WPF相关的UI控件和样式库在Githu也是非常多. 关于UI的部分,可以分为二种: 对控件本身没有很大的需求, 只需要在原有的基础 ...

  5. 回溯算法 - n 皇后问题

    (1)问题描述 在 n × n 格的棋盘上放置彼此不受攻击的 n 个皇后.按照国际象棋的规则,皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子.n 后问题等价于在 n × n 的棋盘上放置 n 个 ...

  6. MySQL获取webshell的几种方式

    select ... into outfile 需要满足的条件 对web目录有写权限 GPC关闭(GPC:是否对单引号转义) 有绝对路径(读文件可以不用,写文件需要) 没有配置secure-file- ...

  7. linux学习笔记全-如何学习linux?

    简介 今天整理文件整理出了好多年前学习linux的笔记 就整理下发布在博客上怕文件形式会误删. linux入门基础对于新手而言不推荐看书!!不推荐看书!!(大牛跳过)先看视频看linuxcast的视频 ...

  8. Xrepo:一个现代化的跨平台 C/C++ 包管理器

    xrepo 是一个基于 Xmake 的跨平台 C/C++ 包管理器. 项目源码 官方文档 它基于 xmake 提供的运行时,但却是一个完整独立的包管理程序,相比 vcpkg/homebrew 此类包管 ...

  9. 详解CorelDRAW中刻刀工具的具体运用

    通过CorelDRAW,我们可以将一个对象拆分为两个对象,使用刻刀工具就可以将对象一分为二,保存为一个由两个或者多个子路径组成的对象,可以指定是否要自动闭合路径,或者是否一直将它们打开. CDR刻刀工 ...

  10. FL Studio入门:如何使用Layer插件叠加音色

    Layer控制器也是FL Studio中一个特别有用的插件,主要用来叠加音色,以及通过Layer通道来控制多个打击乐通道. 下面我们一起来看看叠加音色是怎么做出来的. 1.新建一个空白工程,插入3个3 ...