【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. Dubbo负载均衡与集群容错机制

    1  Dubbo简介 Dubbo是一款高性能.轻量级的开源Java RPC框架,它提供了三大核心能力:面向接口的远程方法调用,智能容错和负载均衡,以及服务自动注册和发现. 作为一个轻量级RPC框架,D ...

  2. 【学习总结】C-翁恺老师-入门-第0周<程序设计与C>

    [学习总结]C-翁恺老师-入门-总 1-首先按视频说的下载编辑器 <DevC++> 并一路默认设置: 安装包下载链接 (我有vc6.0不过预感告诉我老师要用类似CS50里那种命令行编辑器? ...

  3. 18-vue-cli脚手架项目中组件的使用

    在webpack-simple模板中,包括webpck模板.一个.vue文件就是一个组件. 为什么会这样呢?因为webpack干活了!webpack的将我们所有的资源文件进行打包.同时webpack还 ...

  4. php开发之系统函数

    一些常用的php开发之系统函数的使用,可以使我们的开发效率,事倍功半 1) BC高精度函数库 2)

  5. hangfire使用笔记

    1.导入nuget包 2.配置 简单配置后就可以写自己的Job了 注意:Hangfire.RecurringJobExtensions这个扩展支持两种job添加方法:json配置文件和特性.但由于时区 ...

  6. MyEclipse 10.X激活方法

    普遍的激活办法请参考: http://blog.csdn.net/miss_kun/article/details/51819206 http://jingyan.baidu.com/article/ ...

  7. MySQL 字段内容区分大小写

    数据由Oracle 迁入MySQL ,由于之前Oracle区分大小写,MySQL的配置使用了默认配置,导致一些数据导入失败,有的唯一键报错,冲突. 将测试过程记录在下面. 数据库版本:MySQL 5. ...

  8. Git使用:Linux(Ubuntu 14.04 x64)下安装Git并配置连接GitHub

    github是一个非常好的网络代码托管仓库,知晓许久,但是一直没有用起来,最近才开始使用git管理自己的文档和代码. Git是非常强大的版本管理工具,今天就告诉大家,如何在Linux下安装GIt,并且 ...

  9. python之路--反射

    一 . isinstance, type, issubclass isinstance 可以判断该对象是否是XXX家族体系中的(只能往上判断) class Base: pass class Foo(B ...

  10. python之路--内置函数, 匿名函数

    一 . 内置函数 什么是内置函数? 就是python给你提供的. 拿来直接⽤的函数, 比如print., input等等. 字符串类型代码的执⾏ eval() 执⾏字符串类型的代码. 并返回最终结果( ...