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

题面

大意:在一个n*m的矩形中从(1,1)走到(n,m)而且走过的路径是一条回文串,统计方案数

sol:我们考虑从(1,1)和(n,m)两端开始算,这样就只要保证每次经过的字符一样就可以满足回文了,因为一定有一个循环需要枚举步数,知道了步数自然只要知道了x坐标就可以算出y坐标了,于是只要枚举x1和x2了,因为当前这步一定是从上一步转移过来的,就可以滚存了

#include<bits/stdc++.h>
using namespace std;
#define Mod 1000000007
long long n, m, f[2][505][505], ans = 0;
char Map[505][505];
inline void Add(long long &x, long long y){x = (x + y) % Mod;}
int main()
{
    freopen("51nod1503.in","r",stdin);
    while(~scanf("%lld%lld", &n, &m))
    {
        ans = 0;
        for(long long i = 1; i <= n; i++)
            scanf("%s", Map[i] + 1);
        if(Map[1][1] != Map[n][m])
        {
            printf("0\n");
            continue;
        }
        long long cur = 0;
        f[cur][1][n] = 1;
        for(long long step = 1; step <= (n + m - 2) / 2; step++)
        {
            cur ^= 1;
            for(long long i = 1; i <= n; i++)
            for(long long j = 1; j <= n; j++)
                f[cur][i][j] = 0;
            for(long long x1 = 1; x1 <= n && x1 - 1 <= step; x1++)
            for(long long x2 = n; x2 >= 1 && n - x2 <= step; x2--)
            {
                long long y1 = 1 + (step - (x1 - 1));
                long long y2 = m - (step - (n - x2));
                if (Map[x1][y1] != Map[x2][y2]) continue;
                Add(f[cur][x1][x2], f[cur ^ 1][x1 - 1][x2 + 1]);
                Add(f[cur][x1][x2], f[cur ^ 1][x1 - 1][x2]);
                Add(f[cur][x1][x2], f[cur ^ 1][x1][x2 + 1]);
                Add(f[cur][x1][x2], f[cur ^ 1][x1][x2]);
            }
        }
        for(long long i = 1; i <= n; i++)
            Add(ans, f[cur][i][i]);
        if((n + m) & 1)
        for(long long i = 1; i < n; i++)
            Add(ans, f[cur][i][i + 1]);
        printf("%lld\n", ans);
    }
}

原文地址:https://www.cnblogs.com/gaojunonly1/p/9445534.html

时间: 2024-10-26 08:29:53

51nod 1503 猪和回文(dp滚存)的相关文章

1503 猪和回文(DP)

1503 猪和回文 题目来源: CodeForces 基准时间限制:2 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 一只猪走进了一个森林.很凑巧的是,这个森林的形状是长方形的,有n行,m列组成.我们把这个长方形的行从上到下标记为1到n,列从左到右标记为1到m.处于第r行第c列的格子用(r,c)表示. 刚开始的时候猪站在(1,1),他的目标是走到(n,m).由于猪回家心切,他在(r,c)的时候,只会往(r+1,c)或(r,c+1)走.他不能走出这个森林. 这只猪所在的森林是一

51Nod 1503 猪和回文

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1503 思路: 没想到要用DP去解决. 题目是从起点出发走,我们可以从起点和终点各出发一个点,每次两个点各走一步,当然这两步所对应的字符是要一样的. 于是,定义d[step][x1][y2][x2][y2],表示第step时第一个点走到(x1,y1),第二个点走到(x2,y2)时(当然了,这两个点的字符肯定是相同的)的方法数. 因为此时的方法数是基于上一步的情况,所以用滚

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

1 /* 2 题意:给出一串字符(全部是小写字母),添加或删除一个字符,都会产生一定的花费. 3 那么,将字符串变成回文串的最小花费是多少呢? 4 5 思路:如果一个字符串增加一个字符 x可以形成一个回文串,那么从这个字符串中删除这个字符 x 6 同样也能形成回文串! 7 所以我们只记录删除,和增加这个字符 x 的最小的费用就好了!->转变成添加多少个字符形成回文串费用最少! 8 9 str[i]!=str[k] 10 dp[i][j]=min(dp[i][j-1]+cost[str[k]-'a

51nod 1089 最长回文子串 V2(Manacher算法)

1089 最长回文子串 V2(Manacher算法) 基准时间限制:1 秒 空间限制:131072 KB 分值: 0 难度:基础题  收藏  关注 回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串. 输入一个字符串Str,输出Str里最长回文子串的长度. Input 输入Str(Str的长度 <= 100000) Output 输出最长回文子串的长度L. Input示例 daabaac Output示例 5 #include <iostream> #include

51nod 1503 多线程dp

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1503 1503 猪和回文 题目来源: CodeForces 基准时间限制:2 秒 空间限制:131072 KB 分值: 40 难度:4级算法题 收藏 关注 一只猪走进了一个森林.很凑巧的是,这个森林的形状是长方形的,有n行,m列组成.我们把这个长方形的行从上到下标记为1到n,列从左到右标记为1到m.处于第r行第c列的格子用(r,c)表示. 刚开始的时候猪站在(1,1),

codeforce 570 problem E&amp;&amp; 51Nod-1503-猪和回文

1503 猪和回文 一只猪走进了一个森林.很凑巧的是,这个森林的形状是长方形的,有n行,m列组成.我们把这个长方形的行从上到下标记为1到n,列从左到右标记为1到m.处于第r行第c列的格子用(r,c)表示. 刚开始的时候猪站在(1,1),他的目标是走到(n,m).由于猪回家心切,他在(r,c)的时候,只会往(r+1,c)或(r,c+1)走.他不能走出这个森林. 这只猪所在的森林是一个非同寻常的森林.有一些格子看起来非常相似,而有一些相差非常巨大.猪在行走的过程中喜欢拍下他经过的每一个格子的照片.一

后缀数组 - 求最长回文子串 + 模板题 --- ural 1297

1297. Palindrome Time Limit: 1.0 secondMemory Limit: 16 MB The “U.S. Robots” HQ has just received a rather alarming anonymous letter. It states that the agent from the competing «Robots Unlimited» has infiltrated into “U.S. Robotics”. «U.S. Robots» s

51nod 1092 回文字符串 (dp)

http://www.51nod.com/onlineJudge/questionCode.html#!problemId=1092 这个题是poj-3280的简化版,这里只可以增加字符,设 dp[i][j] 为把以i开头j结尾的子串变为回文串的最少次数, if(s[i]==s[j])  dp[i][j]=dp[i+1][j-1]; else dp[i][j]=min(dp[i+1][j],dp[i][j-1])+1; 1 #include <iostream> 2 #include <

51Nod - 1092 回文字符串

51Nod - 1092 回文字符串 回文串是指aba.abba.cccbccc.aaaa这种左右对称的字符串.每个字符串都可以通过向中间添加一些字符,使之变为回文字符串. 例如:abbc 添加2个字符可以变为 acbbca,也可以添加3个变为 abbcbba.方案1只需要添加2个字符,是所有方案中添加字符数量最少的. Input 输入一个字符串Str,Str的长度 <= 1000. Output 输出最少添加多少个字符可以使之变为回文字串. Input示例 abbc Output示例 2 题解