~~~题面~~~

题解:

  首先观察到题目要求的是合法回文串的个数,而回文串要求从前往后和从后往前是一样的,因此我们假设有两只猪,分别从左上和右下开始走,走相同的步数最后相遇,那么它们走的路能拼在一起构成一个回文串,当且仅当它们走字符串是完全相同的。

  那么我们可以根据这个性质进行DP,设f[i][j][k][l]表示第一只猪走到(i, j),第二只猪走到(k, l)的方案数。

  那么观察到$i + j = k + l$,所以$l$是没必要记录的,因为前面三个确定,l就确定了,然后因为i从1 开始枚举,每次只能走一步,所以只会用到上一步的方案,所以可以滚动一下,这样时空复杂度就都可以承受了。

  因为要限制两只猪走的步数一样,注意限制第一只猪在红色的三角形中,另一只猪在蓝色的三角形中。

 #include<bits/stdc++.h>
using namespace std;
#define R register int
#define AC 510
#define mod 1000000007
#define LL long long int n, m;
LL f[][AC][AC], ans;
char s[AC][AC]; void pre()
{
scanf("%d%d", &n, &m);
for(R i = ; i <= n; i ++) scanf("%s", s[i] + );
if(s[][] != s[n][m]) {printf("0\n"); exit();}
} inline bool check(int i, int j, int k, int l)
{
if(i == k && j == l) return true;
else if(i + == k && j == l) return true;
else if(i == k && j + == l) return true;
return false;
} void work()
{
int l, now = , b = (n + m) / ;
f[][][n] = ;
for(R i = ; i <= n; i ++, now ^= )
{
for(R j = ; j + i - <= b; j ++)
{
if(i == && j == ) continue;
for(R k = n; k >= i; k --)
{
l = n + m + - i - j - k;
if(l < j || l > m) continue;
if(s[i][j] != s[k][l]) continue;
f[now][j][k] = f[now ^ ][j][k] + f[now ^ ][j][k + ];
f[now][j][k] += f[now][j - ][k] + f[now][j - ][k + ];
f[now][j][k] %= mod;
if(check(i, j, k, l)) ans += f[now][j][k];
if(ans > mod) ans -= mod;
}
}
memset(f[now ^ ], , sizeof(f[now ^ ]));//因为有同层转移,所以要memset,而不能枚举到它的时候再重置
}
printf("%lld\n", ans);
} void work1()
{
int l, now = , b = (n + m) / ;
f[][][n] = ;
for(R i = ; i <= n; i ++, now ^= )
{
for(R j = ; j + i - <= b; j ++)
{
if(i == && j == ) continue;
for(R k = n; k >= i; k --)
{
l = n + m + - i - j - k;
if(l < j || l > m) continue;
if(s[i][j] != s[k][l]) continue;
f[i][j][k] += f[i - ][j][k] + f[i - ][j][k + ];
f[i][j][k] += f[i][j - ][k] + f[i][j - ][k + ];
f[i][j][k] %= mod;
if(check(i, j, k, l)) ans += f[i][j][k];
if(ans > mod) ans -= mod;
}
}
}
printf("%lld\n", ans);
} int main()
{
// freopen("in.in", "r", stdin);
pre();
work();
// fclose(stdin);
return ;
}

[51nod1503]猪和回文 DP的更多相关文章

  1. 1503 猪和回文(DP)

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

  2. 51nod-1503 猪和回文 - 二维矩阵上的dp

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

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

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

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

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

  5. NYOJ 1023 还是回文(DP,花最少费用形成回文串)

    /* 题意:给出一串字符(全部是小写字母),添加或删除一个字符,都会产生一定的花费. 那么,将字符串变成回文串的最小花费是多少呢? 思路:如果一个字符串增加一个字符 x可以形成一个回文串,那么从这个字 ...

  6. SCUT125 华为杯 D.笔芯回文 —— DP

    题目链接: https://scut.online/p/125 题目描述 bxbx有一个长度一个字符串SS,bxbx可以对其进行若干次操作. 每次操作可以删掉一个长度为k(1 \leq k \leq ...

  7. 【LSGDOJ1383】修改回文 dp

    题目描述 为了跟踪所有的牛,农夫JOHN在农场上装了一套自动系统. 他给了每一个头牛一个电子牌号 当牛走过这个系统时,牛的名字将被自动读入. 每一头牛的电子名字是一个长度为M (1 <= M & ...

  8. 51Nod 1503 猪和回文

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

  9. 1154 回文串划分(DP+Manacher)

    1154 回文串划分 基准时间限制:1 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 有一个字符串S,求S最少可以被划分为多少个回文串. 例如:abbaabaa,有多种划分方式. ...

随机推荐

  1. Asp.NET Core 在IIS部署 An assembly specified in the application dependencies manifest was not found

    今天在发布应用的时候,出来了一个报错:An assembly specified in the application dependencies manifest was not found 情况如下 ...

  2. java元注解(注解在注解上的注解)

    //ElementType.TYPE 给类.接口.枚举上使用 @Target(ElementType.TYPE)//给注解进行注解,表示该注解可以用在什么地方 //@Retention(Retenti ...

  3. Python3爬虫(五)解析库的使用之XPath

    Infi-chu: http://www.cnblogs.com/Infi-chu/ XPath: 全称是 XML Path Language,XML路径语言,它是一门在XML文档中和HTML文档中查 ...

  4. Kubernetes-GC

    Kubernetes集群中垃圾回收(Garbage Collection)机制由kubelet完成.kubelet定期清理不再使用的容器和镜像,每分钟进行一次容器的GC操作,每五分钟进行一次镜像的GC ...

  5. codeforces 845A Chess Tourney

    参考:https://blog.csdn.net/zhongyuchen/article/details/77478039 #include <iostream> #include < ...

  6. ABAP CDS ON HANA-(10)項目結合して一つ項目として表示

    Numeric Functions ABS(arg)  CEIL(arg) DIV(arg1, arg2) DIVISION(arg1, arg2, dec) FLOOR(arg) MOD(arg1, ...

  7. python 字符串输入、输出函数print input raw_input

    一.输出print print输出是以不带引号的输出.(用户所见的输出) 二.input()  和  raw_input()输入函数 raw_input()会把输入数据转换成字符串形式: ------ ...

  8. 汇编实验15:安装新的int 9中断例程

    汇编实验15:安装新的int 9中断例程 任务 安装一个新的int 9中断例程,功能:在DOS下,按下“A”键后,除非不在松开,一旦松开后,就显示满屏幕的“A”,其他键照常处理. 预备知识概要 这次实 ...

  9. svn 服务器搭建 (Linux)

    1.svn目前在程序开发工程汇总应用非常普遍,所以学习svn的环境搭建还是很有必要的 2.本次安装的服务是Subversion(svn)针对的环境是Linux,Subversion(SVN) 是一个开 ...

  10. Oracle 完全理解connect by-详细脚本-可实战

    狒狒Q971751392 未来星开发团队--狒狒(QQ:9715234) oracle树查询的最重要的就是select…start with…connect by…prior语法了.依托于该语法,我们 ...