hihocoder 1149 : 回文字符序列(区间dp)
2016-04-11 22:39
337 查看
题意
时间限制: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.if(s[i] == s[j]) dp[i][j] = dp[i+1][j]+dp[i][j-1]+1; else dp[i][j] = dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1];
简单解释一下,先说一下s[i] != s[j]时,dp[i+1][j]+dp[i][j-1]然后再减去重复的dp[i+1][j-1]部分,这个不难理解。
那么当s[i] == s[j]时,显然i与j之间所有是回文串的子序列可以用s[i],s[j]包裹成为新的子序列,所以重复部分不需要剪去了,还需要加上1是因为s[i]s[j]两个单独一起也可以作为一个回文子序列。
代码
#include <cstdio> #include <iostream> #include <cstdlib> #include <cstring> using namespace std; const int MOD = 100007; char s[1009]; int dp[1009][1009]; int main() { int T; scanf("%d", &T); for(int i=1; i<=T; i++) { memset(dp, 0, sizeof(dp)); scanf("%s", s+1); int n = strlen(s+1); for(int l=0; l<n; l++) { for(int i=1; i+l<=n; i++) { int j = i+l; if(s[i] == s[j]) dp[i][j] = (dp[i+1][j]+dp[i][j-1]+1)%MOD; else dp[i][j] = (dp[i+1][j]+dp[i][j-1]-dp[i+1][j-1]+MOD)%MOD; } } printf("Case #%d: %d\n", i, dp[1] ); } return 0; }
相关文章推荐
- C# DataGridView添加右键菜单等技巧
- 图论(网络流):COGS 410. [NOI2009] 植物大战僵尸
- 编译原理-用FLEX构造词法分析程序
- 如何在eclipse中更改jsp页面的charset以解决中文乱码问题
- 利用select函数实现非阻塞式的socket accept
- 会声会影 X8 安装过程中,提示已安装另一个版本
- MATLAB一个figure中显示多幅图像,并缩小空白区域
- 欢迎使用CSDN-markdown编辑器
- poj—2488骑士的旅程
- inline-block各浏览器兼容以及水平间隙问题解决方案
- 统计多个学生的多门课的成绩(结构体)
- javascript显示动态时间12小时制(二)
- Spark内核源码剖析、Hadoop高端
- Poj 2139 Six Degrees of Cowvin Bacon【floyd】
- const成员 和 static成员
- React-Native系列Android——Native与Javascript通信原理(一)
- iOS自动布局之Autoresizing
- C语言实现推箱子小游戏
- google官方的下拉刷新+自定义上拉加载更多
- laravel 学习笔记1