zoukankan      html  css  js  c++  java
  • Palindromic Paths(DP)

    描述

    Given an N×N grid of fields (1≤N≤500), each labeled with a letter in the alphabet. For example:

    ABCD

    BXZX
    CDXB
    WCBA

    Each day, Susa walks from the upper-left field to the lower-right field, each step taking her either one field to the right or one field downward. Susa keeps track of the string that she generates during this process, built from the letters she walks across. She gets very disoriented, however, if this string is a palindrome (reading the same forward as backward), since she gets confused about which direction she had walked.

    Please help Susa determine the number of distinct routes she can take that correspond to palindromes. Different ways of obtaining the same palindrome count multiple times. Please print your answer modulo 1,000,000,007.

    输入

    The first line of input contains N, and the remaining N lines contain the N rows of the grid of fields. Each row contains N characters that are in the range A...Z.

    输出

    Please output the number of distinct palindromic routes Susa can take, modulo 1,000,000,007.

    样例输入

    4
    ABCD
    BXZX
    CDXB
    WCBA

    样例输出

     12

    提示

    Susa can make the following palindromes

    1 x "ABCDCBA"

    1 x "ABCWCBA"

    6 x "ABXZXBA"

    4 x "ABXDXBA"

     题目大意:

    从左上角走到右下角(每次只能往右或往下)路径组成的串是回文串的路径数。

    分析:可以让左下角和右上角同时开始走,dp[i][j][k]代表走i步左上角走到第j行,右上角走到第k行的回文数。dp[i][j][k]=dp[i-1][j-1][k]+dp[i-1][j-1][k+1]+dp[i-1][j][k]+dp[i-1][j][k+1],由于n最大为500,三维开不下,观察状态转移方程第i步只于第i-1步有关系,所以可以用滚动数组来优化。

    #include <bits/stdc++.h>
    typedef long long ll;
    using namespace std;
    const int MD=1e9+7;
    char s[505][505];
    ll dp[2][505][505];
    int main()
    {
        int n;
        scanf("%d",&n);
        for(int i=1;i<=n;i++)
            scanf("%s",s[i]+1);
        int cnt=0;
        dp[cnt][1][n]=1;
        for(int i=1;i<=n;i++)
        {
            for(int x1=1;x1<=n;x1++)
                for(int x2=1;x2<=n;x2++)
                {
                    int y1=i-x1+1,y2=2*n-x2-i+1;
                    if(y1<=0||y1>n||y2<=0||y2>n) continue;
                    if(s[x1][y1]==s[x2][y2])
                        dp[cnt^1][x1][x2]=(dp[cnt][x1-1][x2]+dp[cnt][x1-1][x2+1]+dp[cnt][x1][x2]+dp[cnt][x1][x2+1])%MD;
                }
            for(int i=1;i<=n;i++)///很重要
                for(int j=1;j<=n;j++)
                    dp[cnt][i][j]=0;
            cnt^=1;
        }
        ll ans=0;
        for(int i=1;i<=n;i++)
            ans+=dp[cnt][i][i];
        printf("%I64d
    ",ans%MD);
        return 0;
    }
  • 相关阅读:
    12个非常不错的javascript类库
    CSS中单位em和rem的区别
    CSS中box-sizing属性的作用
    网页设计中的默认字体样式详解
    jQuery遍历Table表格的行和列
    css常用解决方案
    JS判断字符串小括号是否成对合法
    Less编码规范
    React九宫格抽奖
    n个有序数组,取出k个最大值
  • 原文地址:https://www.cnblogs.com/zdragon1104/p/9498855.html
Copyright © 2011-2022 走看看