1. 程式人生 > >Codeforces 245H Queries for Number of Palindromes:區間dp

Codeforces 245H Queries for Number of Palindromes:區間dp

clu stdio.h span blog href 字符 space sca 題目

題目鏈接:http://codeforces.com/problemset/problem/245/H

題意:

  給你一個字符串s。

  然後有t個詢問,每個詢問給出x,y,問你區間[x,y]中的回文子串的個數。

題解:

  表示狀態:

    dp[x][y] = numbers

    表示區間[x,y]中的回文子串個數。

  找出答案:

    每次詢問:ans = dp[x][y]

  如何轉移:

    dp[x][y] = dp[x][y-1] + dp[x+1][y] - dp[x+1][y-1] + pal[x][y]

    用到了容斥原理。

    pal[x][y]表示子串s[x to y]是否是一個回文串(是為1,不是為0)。

    其中pal[x][y]又有遞推式:

    pal[x][y] = ( s[x]==s[y] && (x+1==y || pal[x+1][y-1]) )

    記憶化搜索就好啦。

  邊界條件:

    if(x>y) dp[x][y] = 0

    if(x==y) dp[x][y] = 1

AC Code:

 1 #include <iostream>
 2 #include <stdio.h>
 3 #include <string
.h> 4 #define MAX_N 5005 5 6 using namespace std; 7 8 int t; 9 int dp[MAX_N][MAX_N]; 10 int pal[MAX_N][MAX_N]; 11 char s[MAX_N]; 12 13 int is_pal(int x,int y) 14 { 15 if(s[x]!=s[y]) return 0; 16 if(x+1==y) return 1; 17 if(pal[x+1][y-1]!=-1) return pal[x+1][y-1]; 18
return pal[x+1][y-1]=is_pal(x+1,y-1); 19 } 20 21 int dfs(int x,int y) 22 { 23 if(dp[x][y]!=-1) return dp[x][y]; 24 if(x>y) return 0; 25 if(x==y) return dp[x][y]=pal[x][y]=1; 26 dp[x][y]=dfs(x,y-1)+dfs(x+1,y)-dfs(x+1,y-1); 27 pal[x][y]=(s[x]==s[y] && (x+1==y || pal[x+1][y-1])); 28 return dp[x][y]=dp[x][y]+pal[x][y]; 29 } 30 31 int main() 32 { 33 scanf("%s%d",s+1,&t); 34 memset(dp,-1,sizeof(dp)); 35 int x,y; 36 while(t--) 37 { 38 scanf("%d%d",&x,&y); 39 printf("%d\n",dfs(x,y)); 40 } 41 }

Codeforces 245H Queries for Number of Palindromes:區間dp