1. 程式人生 > >1503 豬和回文(DP)

1503 豬和回文(DP)

相差 mathjax red 長方形 class span lose F12 種類

1503 豬和回文 題目來源: CodeForces 基準時間限制:2 秒 空間限制:131072 KB 分值: 40 難度:4級算法題

一只豬走進了一個森林。很湊巧的是,這個森林的形狀是長方形的,有n行,m列組成。我們把這個長方形的行從上到下標記為1到n,列從左到右標記為1到m。處於第r行第c列的格子用(r,c)表示。

剛開始的時候豬站在(1,1),他的目標是走到(n,m)。由於豬回家心切,他在(r,c)的時候,只會往(r+1,c)或(r,c+1)走。他不能走出這個森林。

這只豬所在的森林是一個非同尋常的森林。有一些格子看起來非常相似,而有一些相差非常巨大。豬在行走的過程中喜歡拍下他經過的每一個格子的照片。一條路徑被認為是漂亮的當且僅當拍下來的照片序列順著看和反著看是一樣的。也就是說,豬經過的路徑要構成一個回文。

數一數從(1,1)到(n,m)有多少條漂亮路徑。答案可能非常巨大,請輸出對 109+7 取余後的結果。

樣例解釋:有三種可能

技術分享 技術分享 技術分享

Input
單組測試數據。
第一行有兩個整數 n,m (1≤n,m≤500),表示森林的長和寬。
接下來有n行,每行有m個小寫字母,表示每一個格子的類型。同一種類型用同一個字母表示,不同的類型用不同的字母表示。
Output
輸出答案占一行。
Input示例
3 4
aaab
baaa
abba
Output示例
3


//沒什麽好辦法,暴力是不可能的,想貢獻也想不出,動態規劃,好像有點感覺,但是想不清楚,唉,
設 dp[i][j][k][z] 為,從(1,1) 走右和下走到 (i,j) ,從(n,m)走左和上到(k,z) ,並且路徑上的字符完全相同的種數
容易得到:
  dp[i][j][k][z] += dp[i-1][j][k+1][z];
  dp[i][j][k][z] += dp[i-1][j][k][z+1];
  dp[i][j][k][z] += dp[i][j-1][k+1][z];
  dp[i][j][k][z] += dp[i][j-1][k][z+1];
可以發現的是,只需要 dp[i] 和 dp[i-1] ,所以滾動數組優化一維
如果 i j k 知道了的話 z 可以算出,所以再去掉一維,就完美解決這個問題了
技術分享
 1 #include <bits/stdc++.h>
 2 using namespace std;
3 #define LL long long 4 #define MOD 1000000007 5 #define MX 505 6 7 int n, m; 8 char dat[MX][MX]; 9 LL dp[2][MX][MX]; 10 11 int check(int x,int y,int k,int z) 12 { 13 if (x==k&&y==z) return 1; 14 if (x+1==k&&y==z) return 1; 15 if (x==k&&y+1==z) return 1; 16 return 0; 17 } 18 19 int main() 20 { 21 scanf("%d%d",&n,&m); 22 for (int i=1;i<=n;i++) 23 { 24 scanf("%s",dat[i]+1); 25 } 26 if (dat[1][1]==dat[n][m]) 27 dp[1][1][n]=1; 28 LL ans = 0; 29 for (int i=1;i<=n;i++) 30 { 31 for (int j=1;(i+j-1)<=(n+m)/2;j++) 32 { 33 for (int k=n;n+m+2-i-j-k<=m;k--) 34 { 35 int z = n+m+2-i-j-k; 36 if (dat[i][j]==dat[k][z]) 37 { 38 dp[i%2][j][k] += dp[(i-1)%2][j][k+1]; 39 dp[i%2][j][k] += dp[(i-1)%2][j][k]; 40 dp[i%2][j][k] += dp[i%2][j-1][k+1]; 41 dp[i%2][j][k] += dp[i%2][j-1][k]; 42 dp[i%2][j][k] %= MOD; 43 if (check(i,j,k,z)) 44 ans = (ans+dp[i%2][j][k])%MOD; 45 } 46 } 47 } 48 memset(dp[(i-1)%2],0,sizeof(dp[(i-1)%2])); 49 } 50 printf("%lld\n",ans); 51 return 0; 52 }
View Code

 
 

1503 豬和回文(DP)