题目背景

还记得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. bzoj 1684: [Usaco2005 Oct]Close Encounter【数学(?)】

    枚举分母,然后离他最近的分子只有两个,分别判断一下能不能用来更新答案即可 #include<iostream> #include<cstdio> #include<cma ...

  2. bzoj 1604: [Usaco2008 Open]Cow Neighborhoods 奶牛的邻居【切比雪夫距离+并查集+multiset】

    参考:http://hzwer.com/4361.html 坐标开long long,inf开大点 先曼哈顿转切比雪夫(x+y,x-y),距离就变成了max(x',y'): 先按x排序,维护两个指针, ...

  3. bzoj1052覆盖问题(二分+贪心)

    1052: [HAOI2007]覆盖问题 Time Limit: 10 Sec  Memory Limit: 162 MBSubmit: 2446  Solved: 1131[Submit][Stat ...

  4. js angular 时间戳转换成日期格式 年月日 yyyy-MM-dd

    昨天写项目,要把时间戳转换成日期格式发给后端 我就去网上找 看到的一些都不是我想要的 索性自己就写了一个如图 下面是angular 模式 $scope.getMyDate = function(str ...

  5. 微信小程序获取自定义属性值

    写小程序的时候用到了自定义属性,特地来记录一下 特别是这个坑,必须得说一说 wxml <view class='box' bindtap='getValue'> <view clas ...

  6. 源码阅读之LinkedHashMap(JDK8)

    概述 LinkedHashMap继承自HashMap,实现了Map<K,V>接口.其内部还维护了一个双向链表,在每次插入数据,或者访问.修改数据时,会增加节点.或调整链表的节点顺序.以决定 ...

  7. 公司6:JrVue重用布局

    JrVue是我们基于element重新封装的一套组件库;  为了提高开发效率, 方便对代码的统一管理和维护,  我们提供了一些统一的页面布局, 以及项目常用的中小型模块 我在master新拉一个分支J ...

  8. 二分搜索poj106

    Cable master Time Limit: 1000MS   Memory Limit: 10000K Total Submissions: 49944   Accepted: 10493 De ...

  9. mutiset HDOJ 5349 MZL's simple problem

    题目传送门 /* 这题可以用stl的mutiset容器方便求解,我对这东西不熟悉,TLE了几次,最后用读入外挂水过. 题解有O(n)的做法,还以为我是侥幸过的,后来才知道iterator it写在循环 ...

  10. Java 8 (2) 使用Lambda表达式

    什么是Lambda? 可以把Lambda表达式理解为 简洁的表示可传递的匿名函数的一种方式:它没有名称,但它有参数列表.函数主体.返回类型,可能还有一个可以抛出的异常列表. 使用Lambda可以让你更 ...