传送门

题目2 : 回文字符序列

时间限制:2000ms
单点时限:1000ms
内存限制:256MB

描述

给定字符串,求它的回文子序列个数。回文子序列反转字符顺序后仍然与原序列相同。例如字符串aba中,回文子序列为"a", "a", "aa", "b", "aba",共5个。内容相同位置不同的子序列算不同的子序列。

输入

第一行一个整数T,表示数据组数。之后是T组数据,每组数据为一行字符串。

输出

对于每组数据输出一行,格式为"Case #X: Y",X代表数据编号(从1开始),Y为答案。答案对100007取模。

数据范围

1 ≤ T ≤ 30

小数据

字符串长度 ≤ 25

大数据

字符串长度 ≤ 1000

样例输入
5
aba
abcbaddabcba
12111112351121
ccccccc
fdadfa
样例输出
Case #1: 5
Case #2: 277
Case #3: 1333
Case #4: 127
Case #5: 17

题解:

思路来自贲神

一开始看错了题,以为是算回文子串(要求连续),结果题目是算回文子序列(不一定要连续)。

故,用区间dp,搞了好久。。。晕死,最后用的是记忆化dp,没想到递推肿么搞。

看了网上的代码后,发现:我的思路还是有偏差。

递推的转移方程应该为:

if (s[i] == s[j])
dp[i][j] = (dp[i + ][j] + dp[i][j - ] + ) % mod;
else
dp[i][j] = (dp[i + ][j] + dp[i][j - ] - dp[i + ][j - ]) % mod;

结果:AC | NA    提交时间:2015-04-17 16:05:34

贴一份其他人ac的代码:

 #include <iostream>
#include <cstdio>
#include <cstring> using namespace std; const int maxn = ;
char s[maxn];
const int mod = ;
int dp[maxn][maxn]; int solve()
{
memset(dp, , sizeof(dp));
int n = strlen(s); for (int l = ; l <= n; ++l)
{
for (int i = ; i + l < n; ++i)
{
int j = i + l;
if (s[i] == s[j])
dp[i][j] = (dp[i + ][j] + dp[i][j - ] + ) % mod;
else
dp[i][j] = (dp[i + ][j] + dp[i][j - ] - dp[i + ][j - ]) % mod;
}
} return (dp[][n - ]%mod + mod)%mod;
} int main()
{
int T;
cin >> T;
for (int cas = ; cas <= T; ++cas)
{
cin >> s;
printf("Case #%d: %d\n", cas, solve());
}
return ;
}

再贴一发记忆化dp ac的代码:

 #include <iostream>
#include <cstdio>
#include <cstring>
#include <map>
#include <algorithm>
using namespace std; #define mxn 200005
#define LL long long
#define MP make_pair
#define REP(i, a, b) for (int i = a; i <= b; ++i)
#define FOR(i, a, b) for (int i = a; i < b; ++i) #define mod 100007 int dp[][];
char s[]; int F(int l, int r) {
if (dp[l][r] != -) return dp[l][r];
if (l > r) return dp[l][r] = ;
if (l == r) return dp[l][r] = ;
int& ret = dp[l][r];
ret = (F(l + , r) + F(l, r - )) % mod;
if (s[l] == s[r]) ++ret;
else ret -= F(l + , r - );
ret = (ret + mod) % mod;
return ret;
} int main()
{
int cas = , t; scanf("%d", &t);
while (t--) {
memset(dp, -, sizeof(dp));
scanf("%s", s + );
int ans = F(, strlen(s + ));
printf("Case #%d: %d\n", ++cas, ans);
}
return ;
}

我的思路复杂度不好,T了

 #include <cstdio>
#include <cstring>
#include <stack>
#include <vector>
#include <algorithm>
#include <queue>
#include <map>
#include <string>
#include <cmath> #define ll long long
int const N = ;
int const M = ;
int const INF = 0x7fffffff;
int const mod = ; using namespace std; int T,cnt;
int dp[N][N];
char s[N];
int l;
int ans; void ini()
{
scanf("%s",s+);
l=strlen(s+);
memset(dp,-,sizeof(dp));
} int dfs(int st,int en)
{
if(dp[st][en]!=-) return dp[st][en];
if(st>en){
return dp[st][en]=;
}
if(st==en){
return dp[st][en]=;
}
dp[st][en]=dfs(st,en-)+;
// printf(" st=%d en=%d dp=%d\n",st,en,dp[st][en]); int i;
for(i=st;i<en;i++){
if(s[i]==s[en])
dp[st][en]=(dp[st][en]+dfs(i+,en-)+)%mod;
}
return dp[st][en];
} void solve()
{
ans=dfs(,l);
} void out()
{
/*
int i,j;
for(i=1;i<=l;i++){
for(j=i;j<=l;j++){
printf(" i=%d j=%d dp=%d\n",i,j,dp[i][j]);
}
}*/
printf("Case #%d: %d\n",cnt,ans);
} int main()
{
//freopen("data.in","r",stdin);
scanf("%d",&T);
for(cnt=;cnt<=T;cnt++)
// while(T--)
//while(scanf("%d%d",&n,&m)!=EOF)
{
ini();
solve();
out();
} return ;
}

编程之美2015资格赛 题目2 : 回文字符序列 [ 区间dp ]的更多相关文章

  1. 编程之美2015 资格赛 hihocoder 题目2: 回文字符序列

    思路:暴力搜,用BFS的方式,生成每一种可能,再对每一种可能进行判断是否回文,进行统计.严重超时!计算一个25个字符的,大概要20多秒! #include <iostream> #incl ...

  2. HDU 4745 Two Rabbits ★(最长回文子序列:区间DP)

    题意 在一个圆环串中找一个最长的子序列,并且这个子序列是轴对称的. 思路 从对称轴上一点出发,向两个方向运动可以正好满足题意,并且可以证明如果抽选择的子环不是对称的话,其一定不是最长的. 倍长原序列, ...

  3. 合并回文子串(区间dp)

    链接:https://ac.nowcoder.com/acm/problem/13230来源:牛客网 题目描述 输入两个字符串A和B,合并成一个串C,属于A和B的字符在C中顺序保持不变.如" ...

  4. hdu4632 Palindrome subsequence 回文子序列个数 区间dp

    Palindrome subsequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 131072/65535 K (Java/ ...

  5. 便宜的回文串(区间DP)

    题目链接:便宜的回文串 这道题刚开始其实还是没有思路的.没办法,只能看题解了... 其实我们在思考问题时,考虑到一段串增或减时会改变它的长度,所以转移时会麻烦... 但其实不用考虑那么多的问题,我们只 ...

  6. [HIHO1323]回文字符串(区间dp)

    题目链接:http://hihocoder.com/problemset/problem/1323 思路:区间dp,按照区间长度枚举所有区间和区间的起始位置.这时也可获取到区间的末位,比对这两个字符是 ...

  7. hihocoder1323 回文字符串(区间dp)

    https://hihocoder.com/problemset/problem/1323 刚开始真没看出来这是一道dp题.. dp[i][j]表示i~j段修改成回文串所需的最少操作次数.然后根据s[ ...

  8. hihoCoser(#1149 : 回文字符序列)

    时间限制:2000ms 单点时限:1000ms 内存限制:256MB 描述 给定字符串,求它的回文子序列个数.回文子序列反转字符顺序后仍然与原序列相同.例如字符串aba中,回文子序列为"a& ...

  9. 【HIHOCODER 1323】回文字符串(区间DP)

    描述 给定一个字符串 S ,最少需要几次增删改操作可以把 S 变成一个回文字符串? 一次操作可以在任意位置插入一个字符,或者删除任意一个字符,或者把任意一个字符修改成任意其他字符. 输入 字符串 S. ...

随机推荐

  1. STM32 modbus CRC16校验

    typedef unsigned char uint8_t; typedef unsigned short uint16_t; typedef int int32_t; const uint16_t ...

  2. 写给技术lead的招聘指南

    工作这么久,面试过的工程师不下两三百人.大部份招到的人都比靠谱当然也有失败的例子.把亲身经历总结如下: 1. 什么人一定不能招: 理解能力差: 对你提出的问题,答不对题,重复提问.面试官可以在面试当中 ...

  3. git 初识

    现在平时用的都是SVN,感觉还是挺好用的.就是有的时候解决冲突的时候有点麻烦.但这样也是不可避免的. 今天看来下GIT,同样是版本控制,GIT的原理,和SVN还是不一样的.我个人的理解,SVN是对每个 ...

  4. qt QTableView/QTableWidget样式设置

    转载请注明出处:http://www.cnblogs.com/dachen408/p/7591409.html 选中设置: QTableView::item:selected { background ...

  5. cnbeta新闻资讯第三方客户端应用

    该源码案例是一个cnbeta第三方客户端应用案例,作者ywwxhz,源码cnBeta-reader,cnbeta 的 Android 客户端项目. 源码下载: http://code.662p.com ...

  6. 假设在一个 32 位 little endian 的机器上运行下面的程序,结果是多少?

    假设在一个 32 位 little endian 的机器上运行下面的程序,结果是多少? #include <stdio.h> int main(){ , b = , c = ; print ...

  7. Yii1 获取当前请求的url

    echo Yii::app()->getRequest()->getUrl();

  8. 杭电 2120 Ice_cream's world I (并查集求环数)

    Description ice_cream's world is a rich country, it has many fertile lands. Today, the queen of ice_ ...

  9. 南宁2017ICPC总结

    ​    ​    ​     ​    ​ 南宁2017ICPC总结 第二次到南宁,高铁三个半小时好像没什么感觉了,广西的天气真的是又湿又冷,而且交通也及其不方面,所以对广西的印象也不是很好.这次承 ...

  10. [AI开发]基于DeepStream的视频结构化解决方案

    视频结构化的定义 利用深度学习技术实时分析视频中有价值的内容,并输出结构化数据.相比数据库中每条结构化数据记录,视频.图片.音频等属于非结构化数据,计算机程序不能直接识别非结构化数据,因此需要先将这些 ...