【BZOJ5318】[JSOI2018]扫地机器人(动态规划)

题面

BZOJ

洛谷

题解

神仙题。不会。。。。

先考虑如果一个点走向了其下方的点,那么其右侧的点因为要被访问到,所以必定只能从其右上方的点走过来。同理,如果这个点向右,那么其下方的点就只能从其左下方的点向右走过来。

因此我们可以确定所有平行于副对角线的斜线上的位置的方向都是相同的。

考虑\(n=m\)的情况,从一个点开始无论向右开始向下,都只会走到下一条对角线上,因此这个过程本质上就是就是固定了一个向下向右的序列,然后循环这个操作直到结束。

考虑一个序列如果是合法的,假设其向下走\(x\)次,向右走\(n-x\)次,因为是循环这个操作,那么它会走到的列显然就是\(gcd(x,n)\)的倍数,因此当且仅当\(gcd(x,n)=1\)时这个操作序列才会合法。

因此\(n=m\)时答案就是\(\displaystyle \sum_{i=1}^n [gcd(i,n)=1]{n\choose i}\)。

如果\(n\neq m\),令\(d=gcd(n,m)\),(通过看别人写的题解),我们可以知道这个矩形必定被分成若干个\(d*d\)的矩形,并且每个矩形内部的方案都是一样的。(谁会证明就教教我啊QwQ)

那么假设\(i\)是向下走的步数,\(j=d-i\)即向右走的步数。

那么答案就是\(\displaystyle \sum_{i=1}^d[gcd(i,d)=1][gcd(i,n)=1][gcd(j,m)=1]{d\choose i}\)。(\(i,d\)互质和\(j,d\)互质两者是等价的,所以就不用多一个\(j,d\)互质的限制了)

现在考虑有障碍的情况。如果从一个格子\((x,y)\)出发走\(d\)步,那么它必定会到达\((x+i,y+j)\)(因为所有\(d*d\)的矩形都是同构的)。

把题目要求的停止,转为求到达所有障碍的时间的最小值。

把所有障碍分下类,全部可以写成\((x+ki,y+kj)\)的形式,这里的\(1\le x\le i+1,1\le y\le j+1\)。

而最小值只有\(n*m\)个,设\(f[i][j][k]\)表示当前在点\((i,j)\),路径上访问过的障碍的最小值为\(k\)的方案数。

每次枚举合法的一组\(i,j\),然后预处理出离每个\((x+ki,y+kj)\)最近的障碍的距离,这样子就可以大力\(dp\)了。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
#define MOD 998244353
#define MAX 55
void add(int &x,int y){x+=y;if(x>=MOD)x-=MOD;}
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,d,ans,val[MAX][MAX];
int f[MAX][MAX][MAX*MAX];
char g[MAX][MAX];
int Solve(int dx,int dy)
{
memset(f,0,sizeof(f));
f[1][1][val[1][1]]=1;
for(int i=1;i<=dx;++i)
for(int j=1;j<=dy;++j)
for(int k=1;k<=n*m;++k)
{
if(!f[i][j][k])continue;
if(i<dx)add(f[i+1][j][min(k,val[i+1][j])],f[i][j][k]);
if(j<dy)add(f[i][j+1][min(k,val[i][j+1])],f[i][j][k]);
}
int ret=0;
for(int i=1;i<=n*m;++i)ret=(ret+1ll*f[dx][dy][i]*i)%MOD;
return ret;
}
int main()
{
int T=read();
while(T--)
{
n=read(),m=read();d=__gcd(n,m);ans=0;
for(int i=1;i<=n;++i)scanf("%s",g[i]+1);
for(int i=1,j=d-1;i<=d;++i,--j)
{
if(__gcd(i,d)!=1||__gcd(i,n)!=1||__gcd(j,m)!=1)continue;
for(int x=1;x<=i+1;++x)
for(int y=1;y<=j+1;++y)
{
int nx=x,ny=y,dis=x+y-2;val[x][y]=n*m;
do
{
if(g[nx][ny]=='1'){val[x][y]=dis;break;}
nx+=i;ny+=j;dis+=d;
if(nx>n)nx-=n;if(ny>m)ny-=m;
}while(nx!=x||ny!=y);
}
ans=(ans+Solve(i+1,j+1))%MOD;
}
printf("%d\n",ans);
}
return 0;
}

【BZOJ5318】[JSOI2018]扫地机器人(动态规划)的更多相关文章

  1. LGP4588[JSOI2018]扫地机器人

    题解 需要先说明一点东西: 1 同一副对角线方向相同,共有$gcd(n,m)$条不同的副对角线,机器人的行为是一个$gcd(n,m)$的循环:: 如果左上方是$(1,1)$,容易看出所有的路径是从左或 ...

  2. [LeetCode] Robot Room Cleaner 扫地机器人

    Given a robot cleaner in a room modeled as a grid. Each cell in the grid can be empty or blocked. Th ...

  3. Hihocoder 1275 扫地机器人 计算几何

    题意: 有一个房间的形状是多边形,而且每条边都平行于坐标轴,按顺时针给出多边形的顶点坐标 还有一个正方形的扫地机器人,机器人只可以上下左右移动,不可以旋转 问机器人移动的区域能不能覆盖整个房间 分析: ...

  4. Java实现第十届蓝桥杯JavaC组第十题(试题J)扫地机器人

    扫地机器人 时间限制: 1.0s 内存限制: 512.0MB 本题总分:25 分 [问题描述] 小明公司的办公区有一条长长的走廊,由 N 个方格区域组成,如下图所 示. 走廊内部署了 K 台扫地机器人 ...

  5. [LeetCode] 489. Robot Room Cleaner 扫地机器人

    Given a robot cleaner in a room modeled as a grid. Each cell in the grid can be empty or blocked. Th ...

  6. 九度OJ 1408 吃豆机器人 -- 动态规划

    题目地址:http://ac.jobdu.com/problem.php?pid=1408 题目描述: 淘宝公司内部有许多新鲜的小玩具,例如淘宝智能机器人.小时候,大家都玩过那个吃豆子的游戏吧,这机器 ...

  7. LOJ 2550 「JSOI2018」机器人——找规律+DP

    题目:https://loj.ac/problem/2550 只会写20分的搜索…… #include<cstdio> #include<cstring> #include&l ...

  8. 489. Robot Room Cleaner扫地机器人

    [抄题]: Given a robot cleaner in a room modeled as a grid. Each cell in the grid can be empty or block ...

  9. 【LOJ】#2550. 「JSOI2018」机器人

    题解 我不会打表找规律啊QAQ 规律就是 对于\(n = m\)我们每一条左下到右上的对角线上的点的走法都是一样的且每n步一个轮重复 对于\(n != m\)我们找到最大公约数\(d\),在每个\(d ...

随机推荐

  1. .net之httphandler小记

    本地调试代码遇到的一个问题,没有走URL路由器(UrlReWriter : IHttpHandlerFactory),于是网上科普了一下原理,主要有两点: 1.asp.net在处理http请求时,会由 ...

  2. MySQL 通过多个示例学习索引

    最近在准备面试,关于索引这一块,发现很多以前忽略的点,这里好好整理一下 首先为什么要建立索引 一本书,有章.节.段.行这种单位. 如果现在需要找一个内容:第9章>第2节>第3段>第4 ...

  3. 利用php查看某个服务的进程数

    查看进程就是使用ps命令而已,只不顾ps的参数太多了. 使用php查询的话,必须要开启几个函数(可以执行外部程序的函数),参考官网:http://php.net/manual/zh/book.exec ...

  4. c++ 单引号"字符串" 用法

    __int64 flag; //赋值超过4字节,编译错误 //flag = 'ABCDE'; //低于4字节,高位补 0 //flag = 'BCDE'; flag = 'A' << 24 ...

  5. C#复习笔记(4)--C#3:革新写代码的方式(扩展方法)

    扩展方法 扩展方法有以下几个需求: 你想为一个类型添加一些 成员: 你不需要为类型的实例添加任何更多的数据: 你不能改变类型本身, 因为是别人的代码. 对于C#1和C#2中的静态方法,扩展方法是一种更 ...

  6. java 代理模式(静态代理、动态代理、Cglib代理) 转载

    Java的三种代理模式 1.代理模式 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式;即通过代理对象访问目标对象.这样做的好处是:可以在目标对象实现的基础上,增强额外的功能操作,即扩 ...

  7. Python基础知识2-内置数据结构(下)

    bytes.bytearray #思考下面例子: a = 1 b = a print(a == b)#True print(a is b)#True print(id(a) is id(b))#Fal ...

  8. drf开发中常见问题

    开发常见问题及解决 问题: 一.本地系统不能重现的bug 二.api接口出错不能及时的发现或难找到错误栈 三.api文档管理问题 四.大量的url配置造成url配置越来越多难以维护 五.接口不及时去更 ...

  9. DAY03、基本数据类型和运算符

    一.基本数据类型的使用 1.整型int: 作用:用来记录年龄.等级.数量 定义:age=18 使用:数学运算与比较运算: 例:print(10>3) print(10/3) 2.浮点型float ...

  10. js笔记2

    原型:prototype 和 __proto__ prototype 给他即将生成的对象继承下去的属性 prototype: 显式原型,每个function下都有prototype属性,该属性是一个对 ...