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)

时间: 2024-10-05 13:39:30

HDU 5617 Jam's maze(DP)的相关文章

HDU 5617 Jam&#39;s maze 巧妙DP

题意:给你一个字符矩阵,从(1,1)到(n,n)有很多种走法,每一种走法形成一个字符串,问有多少种走法形成的字符串是回文的 分析:(粘贴BC题解) 的是回文串,有人会想到后缀数组自动机马拉车什么的,其实只要求方案数很多,所以我们应该想到动态规划,首先是状态的定义,我们可以想着从(1,1)(1,1)和(n,n)(n,n)开始走,然后走到相遇.所以我们定义状态可以定义为f[x_1][y_1][x_2][y_2]f[x?1??][y?1??][x?2??][y?2??]表示所对应的两个点(x_1,y_

HDU 5617 Jam&#39;s maze dp+滚动数组

题目链接: hdu: http://acm.hdu.edu.cn/showproblem.php?pid=5617 bc(中文):http://bestcoder.hdu.edu.cn/contests/contest_chineseproblem.php?cid=666&pid=1003 题解: 设dp[x1][x2][i]表示第i步时,从(1,1)点走到了(x1,y1),(n,n)点走到了(x2,y2)点的合法的总数. 1 #include<iostream> 2 #include

hdu 5616 Jam&#39;s balance(dp 正反01背包)

来自官方题解: AC代码: 1 #pragma comment(linker, "/STACK:1024000000,1024000000") 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<cmath> 6 #include<math.h> 7 #include<algorithm> 8 #include<queu

hdu 5623 KK&#39;s Number(dp)

问题描述 我们可爱的KK有一个有趣的数学游戏:这个游戏需要两个人,有N\left(1\leq N\leq 5*{10}^{4} \right)N(1≤N≤5∗10?4??)个数,每次KK都会先拿数.每次可以拿任意多个数,直到NN个数被拿完.每次获得的得分为取的数中的最小值,KK和对手的策略都是尽可能使得自己的得分减去对手的得分更大.在这样的情况下,最终KK的得分减去对手的得分会是多少? 输入描述 第一行一个数T\left( 1\leq T\leq 10\right)T(1≤T≤10),表示数据组

HDU 4968 Improving the GPA(dp)

HDU 4968 Improving the GPA 题目链接 dp,最大最小分别dp一次,dp[i][j]表示第i个人,还有j分的情况,分数可以减掉60最为状态 代码: #include <cstdio> #include <cstring> #include <algorithm> using namespace std; int t, avg, n; double dp1[15][405], dp2[15][405]; double get(int x) { if

2014多校第七场1005 || HDU 4939 Stupid Tower Defense (DP)

题目链接 题意 :长度n单位,从头走到尾,经过每个单位长度需要花费t秒,有三种塔: 红塔 :经过该塔所在单位时,每秒会受到x点伤害. 绿塔 : 经过该塔所在单位之后的每个单位长度时每秒都会经受y点伤害. 蓝塔 : 经过该塔所在单位之后,再走每个单位长度的时候时间会变成t+z. 思路 : 官方题解 : 1 #include <cstdio> 2 #include <cstring> 3 #include <iostream> 4 #define LL long long

hdu 4960 Another OCD Patient(dp)2014多校训练第9场

Another OCD Patient                                                                         Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/131072 K (Java/Others) Problem Description Xiaoji is an OCD (obsessive-compulsive disorder) pat

2014多校第四场1005 || HDU 4901 The Romantic Hero (DP)

题目链接 题意 :给你一个数列,让你从中挑选一些数组成集合S,挑另外一些数组成集合T,要求是S中的每一个数在原序列中的下标要小于T中每一个数在原序列中下标.S中所有数按位异或后的值要与T中所有的数按位与的值相同,问能找出多少符合要求的组合. 思路 :比赛的时候有点没有头绪,后来二师兄想出了状态转移方程,YN又改了很多细节,最后才A的.总之是个别扭的DP..... 一开始是 _xor[i][j^a[i]] += _xor[i-1][j] :j 的下一个状态 就是异或上a[i],这个数组所代表的意思

2014多校第一场 E 题 || HDU 4865 Peter&#39;s Hobby (DP)

题目链接 题意 : 给你两个表格,第一个表格是三种天气下出现四种湿度的可能性.第二个表格是,昨天出现的三种天气下,今天出现三种天气的可能性.然后给你这几天的湿度,告诉你第一天出现三种天气的可能性,让你求出最可能出现的天气序列 . 思路 : 定义第 i 天叶子湿度为hum[i].第 i 天,天气为 j 的最大概率为dp[i][j].wealea[i][j]表示天气为 i 叶子为j的概率,weawea[i][j]表示今天天气为 i 明天天气为j的概率,st[i]表示第一天天气为i的概率.pre[i]