#316(DIV 2)パリンドロームパス(DP)丸Codeforces

トピックリンク

質問はから与えられた文字のn×m個のマトリックス(1,1)点に移動することが意図されている(n、m)は文字列のパスに配置される配列中の各文字を通じて指します。今すぐ文字列が必要な回文配列で配置され、モジュロ1E9 + 7の結果をどのように多くのそのようなパスを聞いてきます。

これはそれが本当に立つことができなかったですので、問題は、知らないDapperのではない、これが書かれたdapperの感覚のソリューションに質問です、あきらめて最初から問題への公式なソリューションです。私はこのブログは多くのことを知っているお読みください。

https://blog.csdn.net/u010660276/article/details/47700441

この偉大な見て素晴らしいアイデア、私は理解に少し障害物を追加します。2点のみが、原因制限ステップに横軸を保つものの、実際には、それ以外の場合は、なぜこれほど再帰ために連帯して不明瞭になり、でもDP縦軸は、この意識が明確でなければならない一緒に生き残る配列でありますなぜ余分な答えはありません。この配列を考える時間のアイデアは、DPの縦と再発が明確来るであることを理解することができます。また、本当に理解していないためにどこにすると、それはコメントを無視することができ、コードのコメント知覚問題、内部の問題に、このソリューションの再帰部分。

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mx = 550;
const int _n = 1e9 +7;
int n, m;
char s[mx][mx];
ll dp[2][mx][mx];//上一个状态or当前状态 从(1, 1)开始的点的横坐标 (n, m)开始的点的横坐标
inline ll add(ll a, ll b, ll c, ll d){
    return (a + b + c + d) % _n;
}
int main()
{
    cin >> n >> m;
    for(int i = 1; i <= n; i++){
        scanf("%s", s[i] + 1);
    }
    int cur = 0;
    dp[cur][1][n] = (s[1][1] == s[n][m]);
    for(int step = 1; step <= ((n + m - 2) >> 1); step++){
        int lst = cur;
        cur ^= 1;
        for(int x1 = 1; x1 <= n; x1++)
        for(int x2 = 1; x2 <= n; x2++){
            dp[cur][x1][x2] = 0;
        }
        for(int x1 = 1; x1 <= n && x1 <= 1 + step; x1++)
        for(int x2 = n; x2 >= 1 && x2 >= n - step; x2--){
            int y1 = 1 + step - (x1 - 1);
            int y2 = n - x2 + m - step;
            if(s[x1][y1] != s[x2][y2]) continue;
            dp[cur][x1][x2] = add(dp[lst][x1][x2], dp[lst][x1][x2+1],
                                  dp[lst][x1-1][x2], dp[lst][x1-1][x2+1]);
        }
    }
    ll ans = 0;
    for(int i = 1; i <= n; i++){
        ans += dp[cur][i][i];
        ans %= _n;
    }
    if((m + n) & 1){
        for(int i = 1; i <= n; i++){
            ans += dp[cur][i][i+1];
            ans %= _n;
        }
    }
    cout << ans << endl;
	return 0;
}
 
 
 

おすすめ

転載: blog.csdn.net/xuzonghao/article/details/88935947