题目背景

还记得NOIP2011的寻宝吗?6年之后,小明带着他的妹子小芳,再次走上了寻宝的道路。

然而这次他们寻宝回来之后,小明被困在了一个迷宫中。

题目描述

迷宫是一个n*m的字符矩阵。

小明在这个矩阵的左上角,只能向下和向右走,去和在矩阵右下角的小芳会合。

小明必须将他走过的路径上的,经过的字符收集起来。如果到右下角时他收集到的这些字符连在一起是回文的,那么他就能够走出这个迷宫,否则他就会掉进陷阱出不来。

小明想知道有多少条路径能够让他走出这个迷宫。由于答案可能很大,请对1000000007取模。

输入输出格式

输入格式:

第一行两个整数n和m。

接下来n行,每行m个字符表示这个矩阵,全部均为小写字母

输出格式:

输出一行一个整数表示答案

输入输出样例

输入样例#1:

3 4
aaab
baaa
abba
输出样例#1:

3

说明

对于20%的数据,满足n∗m≤10

对于另外10%的数据,满足字符都是a

对于70%的数据,满足n,m≤60

对于100%的数据,满足n,m≤500

分析:一道比较考验基本功的dp题.

看到题面就应该能想到状态该怎么表示了,设f[i][j][k][l]表示小明走到了(i,j),小芳走到了(k,l)的方案数,那么该怎么转移呢?显然不能顺着推,因为不知道走过的字符串是啥,如果记录的话会有后效性,那么根据回文字符串的特点,小明从起点走,小芳从终点走,如果两个人所在地方的字符是一样的才能继续走,直到两个人碰面,答案累加,因为空间问题可以过70分.

后30%的数据只能开下500*500的数组,也就是说我们只能够保存两维.那么我们可以保存j和l,枚举当前走了多少步,因为方向一定,所以i和k能够推导出来。因为只保存了列的情况,如果直接推的话会计算重复,那么再开一个数组g,记录前一步的状态,f从g转移而来就可以了.

最后统计答案,如果n+m-1是奇数,那么最后汇合的地点一定是同一行,否则有可能是同一行,也有可能相差一行.

总结:这一类dp问题特征就是给你一个n*m的图,规定走的方向,让你求某些值.状态表示比较有规律,一般就是设f[i][j]表示走到了(i,j)的答案.如果题目变通一下让你走两次,那么可以开四维数组来表示状态.有时候也需要变通一下枚举的顺序,依题目而定,规定了走的方向,我们可以只用保存3维就可以推出第4维,可以优化时间,我们也可以保存2维,这样就需要一个辅助数组记录上一步的状态,既优化了时间,也优化了空间.

#include <stack>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm> using namespace std; const int mod = ; int n, m,f[][],g[][];
int dx[] = { , , -, }, dy[] = { , , , - };
long long ans = ;
char s[][]; int main()
{
scanf("%d%d", &n, &m);
for (int i = ; i <= n; i++)
scanf("%s", s[i] + );
if (s[][] == s[n][m])
f[][m] = ;
else
f[][m] = ;
for (int t = ; t < (n + m) / ; t++)
{
for (int i = ; i <= m; i++)
for (int j = ; j <= m; j++)
{
g[i][j] = f[i][j];
f[i][j] = ;
} for (int i = ; i <= m; i++)
for (int j = ; j <= m; j++)
if (g[i][j])
{
int y11 = i, y2 = j, x1 = t - i + , x2 = n - t + m - j + ;
for (int k = ; k < ; k++)
{
for (int l = ; l < ; l++)
{
int nx1 = x1 + dx[k], ny1 = y11 + dy[k];
int nx2 = x2 + dx[l], ny2 = y2 + dy[l];
if (nx1 > n || ny1 > m || nx2 < || ny2 < )
continue;
if (s[nx1][ny1] == s[nx2][ny2])
f[ny1][ny2] = (f[ny1][ny2] + g[i][j]) % mod;
}
}
}
}
if ((n + m - ) & )
{
for (int i = ; i <= m; i++)
ans = (ans + f[i][i]) % mod;
}
else
{
for (int i = ; i <= m; i++)
{
ans = (ans + f[i][i]) % mod;
ans = (ans + f[i][i + ]) % mod;
}
}
printf("%d\n", ans);
return ;
}

noip模拟赛 寻宝之后的更多相关文章

  1. NOIP模拟赛20161022

    NOIP模拟赛2016-10-22 题目名 东风谷早苗 西行寺幽幽子 琪露诺 上白泽慧音 源文件 robot.cpp/c/pas spring.cpp/c/pas iceroad.cpp/c/pas ...

  2. contesthunter暑假NOIP模拟赛第一场题解

    contesthunter暑假NOIP模拟赛#1题解: 第一题:杯具大派送 水题.枚举A,B的公约数即可. #include <algorithm> #include <cmath& ...

  3. NOIP模拟赛 by hzwer

    2015年10月04日NOIP模拟赛 by hzwer    (这是小奇=> 小奇挖矿2(mining) [题目背景] 小奇飞船的钻头开启了无限耐久+精准采集模式!这次它要将原矿运到泛光之源的矿 ...

  4. 大家AK杯 灰天飞雁NOIP模拟赛题解/数据/标程

    数据 http://files.cnblogs.com/htfy/data.zip 简要题解 桌球碰撞 纯模拟,注意一开始就在袋口和v=0的情况.v和坐标可以是小数.为保险起见最好用extended/ ...

  5. 队爷的讲学计划 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的讲学计划 题解:刚开始理解题意理解了好半天,然后发 ...

  6. 队爷的Au Plan CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的Au%20Plan 题解:看了题之后觉得肯定是DP ...

  7. 队爷的新书 CH Round #59 - OrzCC杯NOIP模拟赛day1

    题目:http://ch.ezoj.tk/contest/CH%20Round%20%2359%20-%20OrzCC杯NOIP模拟赛day1/队爷的新书 题解:看到这题就想到了 poetize 的封 ...

  8. CH Round #58 - OrzCC杯noip模拟赛day2

    A:颜色问题 题目:http://ch.ezoj.tk/contest/CH%20Round%20%2358%20-%20OrzCC杯noip模拟赛day2/颜色问题 题解:算一下每个仆人到它的目的地 ...

  9. CH Round #52 - Thinking Bear #1 (NOIP模拟赛)

    A.拆地毯 题目:http://www.contesthunter.org/contest/CH%20Round%20%2352%20-%20Thinking%20Bear%20%231%20(NOI ...

随机推荐

  1. Akka源码分析-Cluster-Distributed Publish Subscribe in Cluster

    在ClusterClient源码分析中,我们知道,他是依托于“Distributed Publish Subscribe in Cluster”来实现消息的转发的,那本文就来分析一下Pub/Sub是如 ...

  2. 贪心 UVA 11729 Commando War

    题目传送门 /* 贪心:按照执行时间长的优先来排序 */ #include <cstdio> #include <algorithm> #include <iostrea ...

  3. docker血一样的教训,生成容器的时候一定要设置数据卷,把数据文件目录,配置文件目录,日志文件目录都要映射到宿主机上保存啊!!!

    打个比方,比如mysql,如果你想重新设置一下mysql的配置,不小心配错里,启动容器失败,已启动就停止了. 根本进不去mysql的容器里.如果之前run容器的时候,没有把数据文件,日志文件,配置文件 ...

  4. VMWare虚拟网络编辑

    VMWare虚拟网络编辑记录. 点击"编辑->虚拟网络编辑器" 在网卡列表中选择"VMnet8"查看目前设置,点击右下角的更改设置进行网络修改. 备注:更 ...

  5. 关于mybatis的xml文件中使用 >= 或者 <= 号报错的解决方案

    当我们需要通过xml格式处理sql语句时,经常会用到< ,<=,>,>=等符号,但是很容易引起xml格式的错误,这样会导致后台将xml字符串转换为xml文档时报错,从而导致程序 ...

  6. 几个不同的tab切换示例

    上一篇<论tab切换的几种实现方法>中讲了tab切换的4种不同实现原理,那么,现在到理论联系实际的时候了,下面就写几个实例. 一.仿”中国人民大学“官网的tab切换,背景是图片,效果图如下 ...

  7. jQuery学习笔记(1)-初探

    一.jQuery是什么 1.jQuery是一套JavaScript脚本库,而不是框架:就好比"System是程序集"是类库,而"ASP.NET MVC"是框架: ...

  8. js一键导出Excel

    HTML: 1 <div class="container"> 2 <table id="backViewTable" class=" ...

  9. Android 比SwipeRefreshLayout更漂亮和强大的下拉刷新控件:Android-MaterialRefreshLayout

    这是一个下拉刷新的控件,它比SwipeRefreshLayout更加漂亮和强大.它易于使用并且支持API LEVEL >= 8.希望你能够喜欢. Now let me talk about Ma ...

  10. get、post、put、delete、head请求方式

    对资源的增,删,改,查操作,其实都可以通过GET/POST完成,不一定要用PUT和DELETE. 一:Jersey框架,实现了restful风格,常用的注解@GET.@POST.@PUT.@DELET ...