P3126 [USACO15OPEN]回文的路径Palindromic Paths

看到这题题解不多,蒟蒻便想更加通俗易懂地分享一点自己的心得,欢迎大佬批评指正_

像这种棋盘形的两边同时做的dp还有

P1006 传纸条,

P1004 方格取数,

T35377 大教室中传纸条

一、思路改进

对于这种题目最暴力的方法无非是分别枚举左上角和右下角两点坐标

f[ i ][ j ][ k ][ l ] = f[ i-1 ][ j ][ k+1 ][ l ] + f[ i-1 ][ j ][ k ][ l+1 ] + f[ i ][ j-1 ][ k+1 ][ l ] + f[ i ][ j-1 ][ k ][ l+1 ]

一起往中间走,即当两个点重合时便有了路径——O(n^4),像这种数据较大的题会爆

于是便有了新的思路,由于两点是一起走的,步数相同,所以可以枚举步数,又因为横纵坐标之和等于所走路径长+1(横纵坐标会重合一点,可以看下图理解),所以只需枚举两点的横坐标(j,k)就可以求出两点的纵坐标

1 2 3 4 5
1 左上角 E
2 D
3 C
4 B
5 A 右下角

i表示步数(注:左上角和右下角只有一种走法,我们可以从第二步开始走,又因为横纵坐标重合一点,为了使横坐标+纵坐标=i,我们可以从3开始枚举

上图字母是路径长为5,i(所枚举的步数)为5+1=6的情况

设j为左边点的横坐标(纵坐标为i-j),k为右边点所走路径的竖直长【如上图点A,枚举到它时k为1,横坐标为n-(i-k)+1=n-i+k+1=5-6+1+1=1,纵坐标为n-k+1=5-1+1=5】

即f(i,j,k)=f(i-1,j,k)+f(i-1,j-1,k)+f(i-1,j,k-1)+f(i-1,j-1,k-1)【j-1,而i不变,说明点的纵坐标+1,其实这个式子与上面暴力的式子是一样的】

二、空间优化

然而,这题数据范围到了500,如果开500^3的数组会MLE,考虑到每次状态转移只需用到f(i-1,j,k),可以用滚动数组优化空间

逆序枚举j、k【f[j][k]=f[j][k]+f[j-1][k-1]+f[j-1][k]+f[j][k-1]等式左侧步数为i,而右侧其实是上次枚举的状态,步数为i-1】(与01背包的滚动数组优化同理)即可避免覆盖还未转移的状态。

三、代码

只有两点字母相同时才能走,因此当两点字母不同时方案数为0,否则为每个可以走过来的状态的方案数之和

具体细节可以在代码中进一步理解

#include<iostream>
#define rint register int
using namespace std;
char a[501][501];
int n;
long long f[501][501],ans;
int main() {
cin>>n;
for (int i=1; i<=n; i++)
for (int j=1; j<=n; j++)
cin>>a[i][j];
if (a[1][1]!=a[n][n]) {
cout<<0;
return 0;
}//如果左上角和右下角字母不同则无解
f[1][1]=1;//当两点分别处于左上角和右下角时方案为1
for (rint i=3; i<=n+1; i++)
for (rint j=i-1; j>=1; j--)
for (rint k=i-1; k>=1; k--) {
if (a[j][i-j]==a[n-i+k+1][n-k+1])//(用j,k分别求出所对应的横纵坐标)此两点字母是否相同?
f[j][k]=(f[j][k]+f[j-1][k-1]+f[j-1][k]+f[j][k-1])%1000000007;
else f[j][k]=0;//不相同则方案为0
}
for (int i=1; i<=n; i++)//统计所有方案数
ans=(ans+f[i][i])%1000000007;//当j=k说明两点重合
cout<<ans;
}

题解 P3126 【[USACO15OPEN]回文的路径Palindromic Paths】的更多相关文章

  1. [USACO15OPEN]回文的路径Palindromic Paths

    [USACO15OPEN]回文的路径Palindromic Paths 题目描述 Farmer John's farm is in the shape of an N \times NN×N grid ...

  2. [USACO15OPEN]回文的路径Palindromic Paths 2.0版

    题目描述 农夫FJ的农场是一个N*N的正方形矩阵(2\le N\le 5002≤N≤500),每一块用一个字母作标记.比如说: ABCD BXZX CDXB WCBA 某一天,FJ从农场的左上角走到右 ...

  3. 洛谷P1206 [USACO1.2]回文平方数 Palindromic Squares

    P1206 [USACO1.2]回文平方数 Palindromic Squares 271通过 501提交 题目提供者该用户不存在 标签USACO 难度普及- 提交  讨论  题解 最新讨论 暂时没有 ...

  4. [译+改]最长回文子串(Longest Palindromic Substring) Part II

    [译+改]最长回文子串(Longest Palindromic Substring) Part II 原文链接在http://leetcode.com/2011/11/longest-palindro ...

  5. [译]最长回文子串(Longest Palindromic Substring) Part I

    [译]最长回文子串(Longest Palindromic Substring) Part I 英文原文链接在(http://leetcode.com/2011/11/longest-palindro ...

  6. 领扣-5 最长回文子串 Longest Palindromic Substring MD

    Markdown版本笔记 我的GitHub首页 我的博客 我的微信 我的邮箱 MyAndroidBlogs baiqiantao baiqiantao bqt20094 baiqiantao@sina ...

  7. USACO 回文的路径

    传送门 这道题和传纸条在某些方面上非常的相似.不过这道题因为我们要求回文的路径,所以我们可以从中间一条大对角线出发去向两边同时进行DP. 这里就有了些小小的问题.在传纸条中,两个路径一定是同时处在同一 ...

  8. 洛谷 P1206 [USACO1.2]回文平方数 Palindromic Squares

    P1206 [USACO1.2]回文平方数 Palindromic Squares 题目描述 回文数是指从左向右念和从右向左念都一样的数.如12321就是一个典型的回文数. 给定一个进制B(2< ...

  9. Leetcode之动态规划(DP)专题-647. 回文子串(Palindromic Substrings)

    Leetcode之动态规划(DP)专题-647. 回文子串(Palindromic Substrings) 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串. 具有不同开始位置或结束位置的子 ...

随机推荐

  1. 在不开启事件循环的线程中使用QTimer(QThread::run函数自带事件循环,在构造函数里创建线程,是一种很有意思的线程用法) good

    引入 QTimer是Qt自带的定时器类,QTimer运行时是依赖于事件循环的,简单来说,在一个不开启事件循环(未调用exec() )的线程中,QTimer是无法使用的.通过分析Qt源码可发现,调用QT ...

  2. 解决SpringBoot多模块发布时99%的问题?SpringBoot发布的8个原则和4个问题的解决方案

    如果使用 SpringBoot 多模块发布到外部 Tomcat,可能会遇到各种各样的问题.本文归纳了以下 8 个原则和发布时经常出现的 4 个问题的解决方案,掌握了这些原则和解决方案,几乎可以解决绝大 ...

  3. python 之 面向对象基础(定义类、创建对象,名称空间)

    第七章面向对象 1.面向过程编程 核心是"过程"二字,过程指的是解决问题的步骤,即先干什么再干什么 基于该思想编写程序就好比在编写一条流水线,是一种机械式的思维方式 优点:复杂的问 ...

  4. Spring注解?啥玩意?

    目录 基础概念:@Bean 和 @Configuration 使用AnnotationConfigApplicationContext 实例化Spring容器 简单的构造 使用register注册IO ...

  5. never下的easysql

    什么是EasySql 在我们早期写的代码中,想实现组装灵活的sql语句与参数,我们可以去翻阅早期自己写的代码 var @sb = new StringBuilder(); sb.Append(&quo ...

  6. JavaScript 操作 DOM 总结

    基本概念 DOM 是 JavaScript 操作网页的接口,全称为"文档对象模型"(Document Object Model).它的作用是将网页转为一个 JavaScript 对 ...

  7. 丢给你一个txt并同时获取你shell

    丢给你一个txt并同时获取你shell 0x00:回顾 <文本编辑器Vim/Neovim被曝任意代码执行漏洞> 听闻很多人知道这个漏洞,但是有一部分人能复现成功,一部分人复现不出来.这里我 ...

  8. Go - Slice 切片

    概述 切片是一种动态数组,比数组操作灵活,长度不是固定的,可以进行追加和删除. len() 和 cap() 返回结果可相同和不同. 声明切片 //demo_7.go package main impo ...

  9. python学习 -女神或者男神把微信消息撤回后好慌,有了这个妈妈再也不担心你看不到女神或者男神撤回的消息了(超详解)

    简介 有时候在忙工作,女朋友发了一个消息,就撤回了,但是人天生的都有一颗好奇心,而且在当今这个时代找个女朋友不容易,一个程序猿找一个女朋友更是不容易的.人家好不容易跟你,你还不得把人家当老佛爷侍候着, ...

  10. 【POJ - 2386】Lake Counting (dfs+染色)

    -->Lake Counting 直接上中文了 Descriptions: 由于近日阴雨连天,约翰的农场中中积水汇聚成一个个不同的池塘,农场可以用 N x M (1 <= N <= ...