HDU 5617 Jam's maze(DP)

Posted AC_Arthur

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 5617 Jam's maze(DP)相关的知识,希望对你有一定的参考价值。

题目链接:点击打开链接

题意:给你一个n*n的矩阵。  求从(1,1)走到(n,n)所组成的回文串个数。

思路:一开始傻逼把状态写成了d[x][y][s],s表示一个串, 用map存的, 后来发现极不可行, 因为这个状态简直太大了, 包括了s串的所有情况。 只是相当于一个dfs中的剪枝罢了。

后来想到, 其实串是不必记录的, 我们只要统计个数, 所以不妨在DP的过程中就判断回文串的情况, 那么就需要同时记录两头的情况。  为了不爆内存, 将状态表示成d[i][x1][x2], 表示走了i步, 左边到了[x1,y1],右边到了[x2,y2], 只要当前位置的字母相同, 就递推过来。  因为有长度这个变量, 只要x坐标就能推出y坐标。

另外形成的回文串一定是奇数,因为n*n矩阵, 一定是2*n - 1个字母。

另外, 滚动数组优化。

细节参见代码:

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<string>
#include<vector>
#include<stack>
#include<bitset>
#include<cstdlib>
#include<cmath>
#include<set>
#include<list>
#include<deque>
#include<map>
#include<queue>
#define Max(a,b) ((a)>(b)?(a):(b))
#define Min(a,b) ((a)<(b)?(a):(b))
using namespace std;
typedef long long ll;
const double PI = acos(-1.0);
const double eps = 1e-6;
const int mod = 5201314;
const int INF = 1000000000;
const int maxn = 500 + 10;
int T,n,m,d[3][maxn][maxn];
char s[maxn][maxn];
int main() {
    scanf("%d",&T);
    while(T--) {
        scanf("%d",&n);
        for(int i=1;i<=n;i++) {
            scanf("%s",s[i]+1);
        }
        memset(d, 0, sizeof(d));
        if(s[1][1] == s[n][n]) d[0][1][n] = 1;
        int u = 1;
        int ans = 0;
        for(int i=1;i<=n-1;i++) {
            for(int j=1;j<=i+1;j++) {
                for(int k=1;k<=i+1;k++) {
                    d[u][j][n-k+1] = 0;
                    int& cur = d[u][j][n-k+1];
                    int x1 = j, x2 = n - k + 1;
                    int ya = i - x1 + 2, yb  = 2 * n - i - x2;
                    if(s[x1][ya] == s[x2][yb]) {
                        cur += d[1-u][x1][x2];
                        cur = (cur + d[1-u][x1-1][x2+1]) % mod;
                        cur = (cur + d[1-u][x1-1][x2]) % mod;
                        cur = (cur + d[1-u][x1][x2+1]) % mod;
                    }
                }
            }
            u = 1 - u;
        }
        for(int i=1;i<=n;i++) {
            ans = (ans + d[1-u][i][i]) % mod;
        }
        printf("%d\n",ans);
    }
    return 0;
}


以上是关于HDU 5617 Jam's maze(DP)的主要内容,如果未能解决你的问题,请参考以下文章

hdu 5615 Jam's math problem(十字相乘判定)

HDU 5619 Jam's store

HDU 5616 Jam's balance 背包DP

HDU 5616 Jam's balance(DP)

HDU 5616 Jam's balance(Jam的天平)

hdu 5618 Jam's problem again