您的位置:首页 > 其它

Codeforces Round #316 (Div. 2) E. Pig and Palindromes

2015-08-14 20:54 429 查看

E. Pig and Palindromes

题目大意

给定一个N*M(N,M <= 500)的字符矩阵,从(1,1)走到(N,M),每次只能向右和向下走,那么有多少种走法可以组成一个回文串。

题目分析

想要形成回文串,显然,从起点出发经过的字符要与从终点出发经过的字符相同。

所以相当于一个点从(1, 1)开始向右或向下走,另一个点从(n, m)开始向左或向上走,并且每次双方走的字符必须相同。

这样就可以用dp的方式求解了,我们可以定义这样一个状态dp[step][x1][x2][y1][y2]。

状态转移有四种:<右走, 下走> * <左走, 上走>

但是有个问题,这样的状态表示是多余的,对于步数step,由于只和上一步有关所以可以用滚动数组优化。

还有一个可以简化的是,我们可以通过x1, x2推算出y1, y2。

最终状态表示为dp[step&1][x1][x2]

还有一个细节就是N+M的奇偶性会影响相遇的位置。

参考代码

[code]#include <bits/stdc++.h>
using namespace std;

typedef long long LL;
const int INF = 0x7fffffff;
const int MOD = 1e9 + 7;
const int N = 500 + 10;

int dp[2]

; // i&1, x0, x1
char str

;

void add(int& x, int v) {
    x += v;
    if(x >= MOD) x -= MOD;
}
int main() {
#ifdef Tally_Ho
    freopen("in.txt", "r", stdin);
#endif // Tally_Ho
    int n, m;
    scanf("%d%d", &n, &m);
    for(int i = 1; i <= n; i++) {
        scanf("%s", &str[i][1]);
    }
    dp[0][1]
 = str[1][1] == str
[m];
    int cur = 0;
    for(int step = 1; step <= (m + n - 2) / 2; step++) {
        cur ^= 1;
        for(int i = 1; i <= n; i++) {
            for(int j = 1; j <= n; j++) {
                dp[cur][i][j] = 0;
            }
        }
        for(int x1 = 1; x1 <= n && x1 - 1 <= step; x1++) {
            for(int x2 = n; x2 >= 1 && n - x2 <= step; x2--) {
                int y1 = 1 + step - (x1 - 1);
                int y2 = m - step + (n - x2);
                if(str[x1][y1] != str[x2][y2]) continue;
                add(dp[cur][x1][x2], dp[cur ^ 1][x1][x2]);
                add(dp[cur][x1][x2], dp[cur ^ 1][x1][x2 + 1]);
                add(dp[cur][x1][x2], dp[cur ^ 1][x1 - 1][x2 + 1]);
                add(dp[cur][x1][x2], dp[cur ^ 1][x1 - 1][x2]);
            }
        }
    }
    int res = 0;
    for(int i = 1; i <= n; i++) {
        add(res, dp[cur][i][i]);
    }
    if((m + n) % 2 == 1) {
        for(int i = 1; i <= n - 1; i++) {
            add(res, dp[cur][i][i + 1]);
        }
    }
    printf("%d\n", res);
    return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: