HDU 4632 Palindrome subsequence(区间DP求回文子序列数)

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4632

题目大意:给你若干个字符串,回答每个字符串有多少个回文子序列(可以不连续的子串)。
解题思路:

设dp[i][j]为[i,j]的回文子序列数,那么得到状态转移方程:
dp[i][j]=(dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+MOD)%MOD
if(str[i]==str[j])
  dp[i][j]+=dp[i-1][j+1]+1

代码:

 1 #include<cstdio>
 2 #include<cmath>
 3 #include<cctype>
 4 #include<cstring>
 5 #include<iostream>
 6 #include<algorithm>
 7 #include<vector>
 8 #include<queue>
 9 #include<set>
10 #include<map>
11 #include<stack>
12 #include<string>
13 #define lc(a) (a<<1)
14 #define rc(a) (a<<1|1)
15 #define MID(a,b) ((a+b)>>1)
16 #define fin(name)  freopen(name,"r",stdin)
17 #define fout(name) freopen(name,"w",stdout)
18 #define clr(arr,val) memset(arr,val,sizeof(arr))
19 #define _for(i,start,end) for(int i=start;i<=end;i++)
20 #define FAST_IO ios::sync_with_stdio(false);cin.tie(0);
21 using namespace std;
22 typedef long long LL;
23 const int N=1e3+5;
24 const int MOD=10007;
25 const int INF=0x3f3f3f3f;
26 const double eps=1e-10;
27
28 int dp[N][N];
29 char str[N];
30
31 int main(){
32     int t,cas=0;
33     cin>>t;
34     while(t--){
35         cin>>str;
36         int n=strlen(str);
37         memset(dp,0,sizeof(dp));
38         for(int i=0;i<n;i++){
39             dp[i][i]=1;
40         }
41         for(int len=1;len<n;len++){
42             for(int i=0;i+len<n;i++){
43                 int j=i+len;
44                 dp[i][j]=(dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+MOD)%MOD;
45                 //如果str[i]==str[j],单独两个字符str[i],str[j]能组成一个回文串,同样也能跟[i-1,j+1]的所有回文串组成新的回文串
46                 if(str[i]==str[j])
47                     dp[i][j]+=dp[i+1][j-1]+1;
48             }
49         }
50         cout<<"Case "<<++cas<<": "<<dp[0][n-1]%MOD<<endl;
51     }
52     return 0;
53 }

原文地址:https://www.cnblogs.com/fu3638/p/8860376.html

时间: 2024-10-11 18:27:56

HDU 4632 Palindrome subsequence(区间DP求回文子序列数)的相关文章

HDU 4632 Palindrome subsequence(区间dp,回文串,字符处理)

题目 参考自博客:http://blog.csdn.net/u011498819/article/details/38356675 题意:查找这样的子回文字符串(未必连续,但是有从左向右的顺序)个数. 简单的区间dp,哎,以为很神奇的东西,其实也是dp,只是参数改为区间,没做过此类型的题,想不到用dp,以后就 知道了,若已经知道[0,i],推[0,i+1], 显然还要从i+1 处往回找,dp方程也简单: dp[j][i]=(dp[j+1][i]+dp[j][i-1]+10007-dp[j+1][

HDU 4632 Palindrome subsequence (区间dp 容斥定理)

Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65535 K (Java/Others) Total Submission(s): 2610    Accepted Submission(s): 1050 Problem Description In mathematics, a subsequence is a sequence that can be derived

hiho 编程之美2015资格赛(回文字符序列-回文子序列数)

题目2 : 回文字符序列 时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定字符串,求它的回文子序列个数.回文子序列反转字符顺序后仍然与原序列相同.例如字符串aba中,回文子序列为"a", "a", "aa", "b", "aba",共5个.内容相同位置不同的子序列算不同的子序列. 输入 第一行一个整数T,表示数据组数.之后是T组数据,每组数据为一行字符串. 输出 对于每组数据

Palindrome subsequence (区间DP)

Palindrome subsequence HDU - 4632 In mathematics, a subsequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements. For example, the sequence <A, B, D> is a subseque

hdu 4632 Palindrome subsequence

In mathematics, a subsequence is a sequence that can be derived from another sequence by deleting some elements without changing the order of the remaining elements. For example, the sequence <A, B, D> is a subsequence of <A, B, C, D, E, F>. (

Palindrome - URAL - 1297(求回文串)

题目大意:RT 分析:后缀数组求回文串,不得不说确实比较麻烦,尤其是再用线段数进行查询,需要注意的细节地方比较多,比赛实用性不高......不过练练手还是可以的. 线段数+后缀数组代码如下: =========================================================================================================================================== #include<stdio

HDU 4632 Palindrome subsequence(区间dp)

Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65535 K (Java/Others) Total Submission(s): 2595    Accepted Submission(s): 1039 Problem Description In mathematics, a subsequence is a sequence that can be derived

POJ 3280 Cheapest Palindrome(区间DP求改成回文串的最小花费)

题目链接:http://poj.org/problem?id=3280 题目大意:给你一个字符串,你可以删除或者增加任意字符,对应有相应的花费,让你通过这些操作使得字符串变为回文串,求最小花费.解题思路:比较简单的区间DP,令dp[i][j]表示使[i,j]回文的最小花费.则得到状态转移方程: dp[i][j]=min(dp[i][j],min(add[str[i]-'a'],del[str[i]-'a'])+dp[i+1][j]); dp[i][j]=min(dp[i][j],min(add[

HDU 4745 Two Rabbits(最长回文子序列)

http://acm.hdu.edu.cn/showproblem.php?pid=4745 题意: 有一个环,现在有两只兔子各从一个点开始起跳,一个沿顺时针,另一个沿逆时针,只能在一圈之内跳,并且每次所在的点的大小必须相同,问最多能经过 几个点. 思路:环状的话可以先倍增改成链. 这道题目的话就是求最长回文子串,它的求法是这样的: 设字符串为str,长度为n,p[i][j]表示第i到第j个字符间的子序列的个数(i<=j),则: 状态初始条件:dp[i][i]=1 (i=0:n-1) 状态转移方