$n \leq 100,m \leq 100$,$n*m$的01矩形,问从左下角开始往上走,每次转弯只能向右,不能经过重复点,不能撞到1,到达点$(x,y)$的方案数,$mod \ \ k$。

感人肺腑的细节题写了一天。。

可以发现他在做一个绕圈运动,运动的过程中逐渐限制自己的活动范围,因此可以用活动范围和射入方向表示状态(这样也就确定了它的位置),$f[L][R][U][D][0123]$--沿左边向上、沿上边向右、沿右边向下、沿下边向左射入矩形$[L,R,U,D]$的方案。如图:

这样转移可以用一个前缀和转移。比如上转右的:

用纵方向一个前缀的蓝色矩形转移到右方向的一个矩形。这样就可以$O(1)$转移了。

由于四维开不下,要把L那一维滚动掉,所以记前缀和的时候,左转上那个数组不要清,那里实际保留了所有$L_2<L$转移到$L$的状态的前缀和。

记答案的时候,在目标处转弯时记录答案。注意最后一圈不要记重了。这句话是啥意思我也说不清,看代码吧QAQ

 //#include<iostream>
#include<cstring>
#include<cstdlib>
#include<cstdio>
//#include<time.h>
//#include<complex>
#include<algorithm>
#include<stdlib.h>
using namespace std; int n,m,mod,tx,ty;
#define maxn 111
int f[][maxn][maxn][maxn][],cur,sum[maxn][maxn][maxn][],bl[maxn][maxn][]; char s[maxn];
bool mp[maxn][maxn]; //0 up 1 right 2 down 3 left
int main()
{
scanf("%d%d%d%d%d",&n,&m,&mod,&ty,&tx);
for (int i=;i<=n;i++)
{
scanf("%s",s+);
for (int j=;j<=m;j++) mp[i][j]=(s[j]=='+');
} for (int j=;j<=m;j++)
{
bl[][j][]=;
for (int i=;i<=n;i++) if (mp[i][j]) bl[i][j][]=bl[i-][j][];
else bl[i][j][]=i;
}
for (int i=;i<=n;i++)
{
bl[i][m+][]=m+;
for (int j=m;j;j--) if (mp[i][j]) bl[i][j][]=bl[i][j+][];
else bl[i][j][]=j;
}
for (int j=;j<=m;j++)
{
bl[n+][j][]=n+;
for (int i=n;i;i--) if (mp[i][j]) bl[i][j][]=bl[i+][j][];
else bl[i][j][]=i;
}
for (int i=;i<=n;i++)
{
bl[i][][]=;
for (int j=;j<=m;j++) if (mp[i][j]) bl[i][j][]=bl[i][j-][];
else bl[i][j][]=j;
}
cur=; for (int i=;i<=n;i++) sum[m][i][n][]=; int ans=;
for (int L=;L<=ty+;L++)
{
cur^=;
for (int R=m;R>=ty;R--) for (int U=;U<=tx;U++) for (int D=max(U,tx);D<=n;D++)
{
sum[R][U][D][]=sum[R+][U][D][];
f[cur][R][U][D][]=;
if (bl[D][L-][]<U)
{
f[cur][R][U][D][]=sum[R][U][D][];
sum[R][U][D][]+=f[cur][R][U][D][]; sum[R][U][D][]-=sum[R][U][D][]>=mod?mod:;
}
if (L-==ty && U==tx) ans+=f[cur][R][U][D][],ans-=ans>=mod?mod:;
}
if (L==ty+) break;
for (int D=n;D>=tx;D--) for (int R=ty;R<=m;R++) for (int U=;U<=tx+;U++)
{
sum[R][U][D][]=sum[R][U][D+][];
f[cur][R][U][D][]=;
if (bl[U-][L-][]>R)
{
f[cur][R][U][D][]=sum[R][U-][D][];
sum[R][U][D][]+=f[cur][R][U][D][]; sum[R][U][D][]-=sum[R][U][D][]>=mod?mod:;
}
if (U-==tx && R==ty) ans+=f[cur][R][U][D][],ans-=ans>=mod?mod:;
}
for (int D=n;D>=tx;D--) for (int R=ty;R<=m;R++) sum[R][][D][]=sum[R][][D+][];
for (int U=;U<=tx;U++) for (int D=max(tx,U);D<=n;D++) for (int R=ty-;R<m;R++)
{
f[cur][R][U][D][]=;
if (bl[U][R+][]>D)
{
f[cur][R][U][D][]=sum[R+][U][D][];
sum[R][U][D][]+=f[cur][R][U][D][]; sum[R][U][D][]-=sum[R][U][D][]>=mod?mod:;
}
if (D==tx && R+==ty) ans+=f[cur][R][U][D][],ans-=ans>=mod?mod:;
}
for (int U=;U<=tx;U++) for (int D=tx-;D<=n;D++) for (int R=ty;R<=m;R++)
{
if (U) sum[R][U][D][]=sum[R][U-][D][];
f[cur][R][U][D][]=;
if (bl[D+][R][]<L)
{
f[cur][R][U][D][]=sum[R][U][D+][];
sum[R][U][D][]+=f[cur][R][U][D][]; sum[R][U][D][]-=sum[R][U][D][]>=mod?mod:;
}
if (D+==tx && L==ty) ans+=f[cur][R][U][D][],ans-=ans>=mod?mod:;
}
for (int U=;U<=tx;U++) for (int R=ty;R<=m;R++) sum[R][U][n][]=sum[R][U-][n][];
}
printf("%d\n",ans);
return ;
}

BZOJ1126: [POI2008]Uci的更多相关文章

  1. 1126: [POI2008]Uci

    1126: [POI2008]Uci https://lydsy.com/JudgeOnline/problem.php?id=1126 分析: dp.状态很妙,就是有点难写. 能走的是一个矩形.首先 ...

  2. bzoj AC倒序

    Search GO 说明:输入题号直接进入相应题目,如需搜索含数字的题目,请在关键词前加单引号 Problem ID Title Source AC Submit Y 1000 A+B Problem ...

  3. [BZOJ1112][POI2008]砖块Klo

    [BZOJ1112][POI2008]砖块Klo 试题描述 N柱砖,希望有连续K柱的高度是一样的. 你可以选择以下两个动作 1:从某柱砖的顶端拿一块砖出来,丢掉不要了. 2:从仓库中拿出一块砖,放到另 ...

  4. [bzoj1122][POI2008]账本BBB

    1122: [POI2008]账本BBB Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 402  Solved: 202[Submit][Status ...

  5. BZOJ 1113: [Poi2008]海报PLA

    1113: [Poi2008]海报PLA Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1025  Solved: 679[Submit][Statu ...

  6. BZOJ 1116: [POI2008]CLO

    1116: [POI2008]CLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 922  Solved: 514[Submit][Status][ ...

  7. BZOJ 1112: [POI2008]砖块Klo

    1112: [POI2008]砖块Klo Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1736  Solved: 606[Submit][Statu ...

  8. BZOJ 1124: [POI2008]枪战Maf

    1124: [POI2008]枪战Maf Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 617  Solved: 236[Submit][Status ...

  9. BZOJ 1123: [POI2008]BLO

    1123: [POI2008]BLO Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 1030  Solved: 440[Submit][Status] ...

随机推荐

  1. 在CentOS上把Git从1.7.1升级到1.7.12.4

    在CentOS上把Git从1.7.1升级到1.7.12.4 摘要:本文记录了在CentOS 6.3上,把Git从1.7.1升级到1.7.12.4的过程. 1. 概述 在我做的一个项目中,最近我对生产服 ...

  2. layer设置弹出全屏

    //弹出即全屏 var index = layer.open({ type: , content: 'http://www.layui.com', area: ['300px', '195px'], ...

  3. [Github筆記] 清除所有 Commit 紀錄

    # 把原來的 git 移除掉 sudo rm .git -r # 初始化 git init git remote add origin https://github.com/username/repo ...

  4. PHP 中空字符串介绍0、null、empty和false之间的关系

    0是数字,是empty,是false,不是null,值相当于空字符串,但类型不是字符串,去空格或强制转换为字符串型时不等于空字符串 ""的值相当于0,是empty,是空字符串,是f ...

  5. HashMap和HashTable的理解与区别

    Hashtable是java一开始发布时就提供的键值映射的数据结构,而HashMap产生于JDK1.2.虽然Hashtable比HashMap出现的早一些,但是现在Hashtable基本上已经被弃用了 ...

  6. Linux-03 Linux下的tar命令

    功能说明 用来建立,还原备份文件的工具程序,它可以加入,解开备份文件内的文件 参数 -c: 建立压缩档案 -x:解压 -t:查看内容 -r:向压缩归档文件末尾追加文件 -u:更新原压缩包中的文件 这五 ...

  7. python3 yum not found

    vi /urs/bin/yum 将#!/usr/bin/python的python改为python2.x(你系统的python2的版本)

  8. node程序的部署神器pm2的基本使用

    pm2是从nodejs衍生出来的服务器进程管理工具,可以做到开机就启动nodejs.当然了,也可以用nohup来做这件事情的. 前言 众所周知,Node.js运行在Chrome的JavaScript运 ...

  9. C++位域和内存对齐问题

    1. 位域: 1. 在C中,位域可以写成这样(注:位域的数据类型一律用无符号的,纪律性). struct bitmap { unsigned a : ; unsigned b : ; unsigned ...

  10. SQL Sever中多列拼接成一列值为NULL

    查询出数据 SELECT a.ID AS KYMain_ID , ',' + a.Leader + ',' AS KYMain_Leader , ), b.TaskLeader) FROM TB_KY ...