题目链接

一只猪走进了一个森林。很凑巧的是,这个森林的形状是长方形的,有n行,m列组成。我们把这个长方形的行从上到下标记为1到n,列从左到右标记为1到m。处于第r行第c列的格子用(r,c)表示。

刚开始的时候猪站在(1,1),他的目标是走到(n,m)。由于猪回家心切,他在(r,c)的时候,只会往(r+1,c)或(r,c+1)走。他不能走出这个森林。

这只猪所在的森林是一个非同寻常的森林。有一些格子看起来非常相似,而有一些相差非常巨大。猪在行走的过程中喜欢拍下他经过的每一个格子的照片。一条路径被认为是漂亮的当且仅当拍下来的照片序列顺着看和反着看是一样的。也就是说,猪经过的路径要构成一个回文。

数一数从(1,1)到(n,m)有多少条漂亮路径。答案可能非常巨大,请输出对 109+7 取余后的结果。

样例解释:有三种可能

  

Input
单组测试数据。
第一行有两个整数 n,m (1≤n,m≤500),表示森林的长和宽。
接下来有n行,每行有m个小写字母,表示每一个格子的类型。同一种类型用同一个字母表示,不同的类型用不同的字母表示。

-----------------------------------------------------------------------------------------------------------------------------------------------

dp(i,j,x,y)代表从(i,j)到(x,y)的路径数则:

dp(i,j,x,y) =  { char(i,j)==char(x,y) ? [dp(i+1,j,x-1,y)+dp(i+1,j,x,y-1)+dp(i,j+1,x-1,y)+dp(i,j+1,x,y-1)] : 0;}

(i,j) 位于上三角,(x,y)位于下三角。从中间分界线向两个顶点处转移。

时间复杂度为N^3,因为状态转移只与上一次的状态相关,所以开两个N*N的数组即可。

#define  _CRT_SECURE_NO_WARNINGS
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
const int N = ;
const int MOD = 1e9 + ;
typedef long long LL;
typedef pair<int, int> int2; LL dp[][N][N];
char maze[N][N];
int n, m, dim;
int level;
int2 coordu, coordl;
bool flag = true;
inline int Cnt(){ return std::min(dim, level + ); }
char upper(int id){
coordu.first = (level<n) ? (level - id) : (n - - id);
coordu.second = level - coordu.first;
return maze[coordu.first][coordu.second];
}
char lower(int id){
coordl.second = (level < m) ? (m - - level+id) : id;
coordl.first = m + n - - level - coordl.second;
return maze[coordl.first][coordl.second];
}
int packu(){
if (coordu.first + >= n) return -;
return ((level + <n) ? (level + ) : (n - )) - coordu.first - ;
}
int packl(){
if (coordl.second - <) return -;
return coordl.second - - ((level + <m) ? (m - - level - ) : ());
}
int main(){
cin >> n >> m; dim = std::min(m, n);
for (int i = ; i<n; i++) scanf("%s", maze[i]);
memset(dp, , sizeof(dp)); level = (m + n) / - ;
bool ismid = true;
while (level >= ){
flag = !flag;
int maxc = Cnt();
for (int i = ; i<maxc; i++) for (int j = ; j<maxc; j++){
char cu = upper(i);
char cl = lower(j);
if (cu == cl){
if (ismid) dp[flag][i][j] = ((coordu.first == coordl.first) || (coordu.second == coordl.second));
else{
int ii = packu(); int jj = packl();
dp[flag][i][j] = ;
if (ii >= && jj >= ) dp[flag][i][j] += dp[!flag][ii][jj];
if (ii + >= && jj >= ) dp[flag][i][j] += dp[!flag][ii + ][jj];
if (ii >= && jj + >= ) dp[flag][i][j] += dp[!flag][ii][jj + ];
dp[flag][i][j] += dp[!flag][ii + ][jj + ];
dp[flag][i][j] %= MOD;
}
}
else dp[flag][i][j] = ;
}
level--; ismid = false;
}
std::cout << dp[flag][][] << endl;
return ;
}

51nod-1503 猪和回文 - 二维矩阵上的dp的更多相关文章

  1. 51nod 1503 猪和回文(dp滚存)

    题面 大意:在一个n*m的矩形中从(1,1)走到(n,m)而且走过的路径是一条回文串,统计方案数 sol:我们考虑从(1,1)和(n,m)两端开始算,这样就只要保证每次经过的字符一样就可以满足回文了, ...

  2. 51nod 1503 猪和回文(多线程DP)

    虚拟两个点,一个从左上角开始走,一个从右下角开始走,定义dp[i][j][k]表示走了i步后,第一个点横向走了j步,第二个点横向走了k步后形成的回文方法种数. 转移方程显然可得,然后滚动数组搞一搞. ...

  3. 51Nod 1503 猪和回文

    http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1503 思路: 没想到要用DP去解决. 题目是从起点出发走,我们可以从起点 ...

  4. 1503 猪和回文(DP)

    1503 猪和回文 题目来源: CodeForces 基准时间限制:2 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 一只猪走进了一个森林.很凑巧的是,这个森林的形状是长方形的,有 ...

  5. hdu_5677_ztr loves substring(回文+二维多重背包)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=5677 题意:给你N个串,问能否选出小于K个回文字符串使得选出的字符串的长度之和为L. 题解:很容易想到 ...

  6. 最大子矩阵和(二维矩阵转一维DP)

    题目描述 蒜头君拿到了一个矩阵,他想知道其中的最大非空子矩阵和是多少. 输入格式 第一行输入两个整数 n,m代表这个矩阵的行数和列数.接下来n行,每行m个整数 ai1,ai2,ai3⋯aim.(1≤m ...

  7. 寻路优化(一)——二维地图上A*启发函数的设计探索

    工作中需要优化A*算法,研究了一天,最后取得了不错的效果.看网上的朋友还没有相关的研究,特此记录一下.有错误欢迎大家批评指正.如需转载请注明出处,http://www.cnblogs.com/Leon ...

  8. [LeetCode] Search a 2D Matrix II 搜索一个二维矩阵之二

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  9. [LeetCode] Search a 2D Matrix 搜索一个二维矩阵

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

随机推荐

  1. Spark RDD概念学习系列之RDD接口

    不多说,直接上干货!

  2. Centos7 minimal 系列之rabbitmq的理解(九)

    一.前言 传送门:rabbitmq安装 第一次接触消息队列,有很多不熟悉的地方,可能也有很多写的不对的,大家一起学习. RabbitMQ是一个在AMQP基础上完成的,可复用的企业消息系统. 使用场景: ...

  3. 图片词典 Picture Dictionary

    图片词典/可视词典 Picture Dictionary 某些 APP 又有新功能可以加入了.

  4. Core Java(六)

    面向对象语言特性 (一) (一)  static 作用于 变量,方法,代码块 静态变量:被类的所有对象共享   在类加载时被加载   优先于对象 Student.country = "中国& ...

  5. UVa 10106 Product 【大数相乘】WA

    虽然是错的代码,但是还是想贴出来,最开始WA发现是没有考虑到乘积为0的情况,后来把a*0,0*a,a*0---0(若干个0),0--0(若干个0)*a都考虑进去了:可是还是WA,实在不懂先留在这儿. ...

  6. 【AnjularJS系列3 】 — 数据的双向绑定

    第三篇,双向的数据绑定 数据绑定是AnguarJS的特性之一,避免书写大量的初始代码从而节约开发时间 数据绑定指令提供了你的Model投射到view的方法.这些投射可以无缝的,毫不影响的应用到web应 ...

  7. ZBrush中遮罩的概念及使用

    刚接触设计软件的小伙伴有可能不知道什么叫做遮罩,遮罩的概念是什么,顾名思义,遮罩就是可以将局部进行遮挡,使用它可以锁定和保护我们不想改变的模型位置,即被遮罩的部分将不参与任何编辑. ZBrush®软件 ...

  8. 使用jd-gui+javassist修改已编译好的class文件

    1.原因:因为公司代码管理不当导致源码丢失,只好已编译好的class文件进行修改 2.首先先在myeclipse中新建java项目并导入javassist 3.将需要修改的文件放到指定文件夹下 4.. ...

  9. 手写一个promise

    Promise A+ 规范:https://promisesaplus.com/ 注:以下代码没有通过 promises-aplus-tests 的全部测试,但基本功能还是全的( 测试结果: 864 ...

  10. 改变浏览器页面默认滚动条样式scrollbar

    scrollbar-3d-light-color 设置或检索滚动条亮边框颜色scrollbar-highlight-color 设置或检索滚动条3D界面的亮边(ThreedHighlight)颜色sc ...