标签:
题目链接:http://codeforces.com/problemset/problem/245/H
题目大意:给你一个字符串s,对于每次查询,输入为一个数对(i,j),输出s[i..j]之间回文串的个数。
容斥原理: dp[i][j] = dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1];
if( str[i]==str[j] 并且 str[i+1..j-1]是回文串 ) dp[i][j]++;
代码:
1 #include <cstdio> 2 #include <cstring> 3 #include <algorithm> 4 #include <vector> 5 #include <map> 6 #include <set> 7 #include <bitset> 8 #include <cmath> 9 #include <numeric> 10 #include <iterator> 11 #include <iostream> 12 #include <cstdlib> 13 #include <functional> 14 #include <queue> 15 #include <stack> 16 #include <string> 17 using namespace std; 18 #define PB push_back 19 #define MP make_pair 20 #define SZ size() 21 #define ST begin() 22 #define ED end() 23 #define CLR clear() 24 #define ZERO(x) memset((x),0,sizeof(x)) 25 typedef long long LL; 26 typedef unsigned long long ULL; 27 typedef pair<int,int> PII; 28 const double EPS = 1e-8; 29 30 const int MAX_N = 5555; 31 char str[MAX_N]; 32 int dp[MAX_N][MAX_N]; 33 int q; 34 35 bool IsPalindromes(int i,int j){ 36 if(i>=j) return true; 37 return dp[i][j] == dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+1; 38 } 39 40 int main() { 41 scanf("%s",str+1); 42 int length = strlen(str+1); 43 // printf("length: %d\n",length); 44 for(int i=1;i<=length;i++) dp[i][i] = 1; 45 46 for(int len = 2; len<=length; len++) { 47 for(int i=1;i<=length;i++) { 48 int j = i+len-1; 49 if( j>length ) continue; 50 dp[i][j] = dp[i][j-1]+dp[i+1][j]-dp[i+1][j-1]; 51 if( str[i]==str[j] ) { 52 if( IsPalindromes(i+1,j-1) ) { 53 dp[i][j] ++ ; 54 } 55 } 56 } 57 } 58 59 // for(int i=1;i<=length;i++) { 60 // for(int j=1;j<=length;j++) { 61 // printf("%d ",dp[i][j]); 62 // } 63 // puts(""); 64 // } 65 66 scanf("%d",&q); 67 68 while( q-- ) { 69 int l,r; 70 scanf("%d%d",&l,&r); 71 printf("%d\n",dp[l][r]); 72 } 73 74 return 0; 75 }
[CF245H] Queries for Number of Palindromes (容斥原理dp计数)
标签:
原文地址:http://www.cnblogs.com/llkpersonal/p/4526918.html