【CF 570E】Pig and Palindromes

【CF 570E】Pig and Palindromes

三维dp 找对应步数的组合数目 二三维分别表示离1,1 和 n,m该步数的回文种类 如果吧状态数都存下内存太大 开个滚动dp数组(最近刚学的)

代码如下:

#include <iostream>
#include <cstdio>
#include <cstring>
#define mod 1000000007
#define ll long long

using namespace std;

char str[501][502];
ll dp[2][501][501];

int main()
{
    int n,m,sp,i,e,j,k,y1,y2;
    ll ans;
    scanf("%d %d",&n,&m);
    for(i = 1; i <= n; ++i) scanf("%s",str[i]+1);

    if(str[1][1] != str[n][m])
    {
        puts("0");
        return 0;
    }

    dp[0][1][n] = 1;
    sp = n+m-2>>1;
    for(e = 1,i = 1; i <= sp; ++i, e ^= 1)
    {
        memset(dp[e],0,sizeof(dp[e]));
        for(j = 1; j <= min(i+1,n); ++j)
            for(k = n; k >= j && k >= max(n-i,1); --k)
            {
                y1 = i+2-j, y2 = m-i+n-k;
                if(str[j][y1] != str[k][y2]) continue;
                dp[e][j][k] = (dp[e^1][j-1][k] + dp[e^1][j][k+1] + dp[e^1][j-1][k+1]+dp[e^1][j][k])%mod;
            }
    }

    ans = 0;
    e ^= 1;
    if(n+m&1)
    {
        for(i = 1; i <= n; ++i) ans = (ans+dp[e][i][i]+dp[e][i][i+1])%mod;
    }
    else
    {
        for(i = 1; i <= n; ++i) ans = (ans+dp[e][i][i])%mod;
    }
    printf("%lld\n",ans);
    return 0;
}

你可能感兴趣的:(dp)