uva10617
2016-02-29 19:36
211 查看
题目大意:
问有几种删除字符的方法可以使得该字符串为回文。
思路:
记忆化搜索。
状态转移方程:
if(s[i] == s[j]) , 那么 dp[i][j] = dp[i + 1][j] + dp[i][ j - 1] - dp[i + 1][j - 1] + dp[i + 1][j - 1] + 1;
dp[i][j]表示的是从i到j最多可以有几个不同的回文串。 回文串不同那么自然删除的方法就不一样了。
dp[i][j] 是由 i + 1到j的回文串数和i到j - 1的回文串数组成的,然而中间的i + 1到j - 1的回文串多算了一次 因此要减去,但是s[i] == s[j]的时候,i + 1 到j - 1的每个回文串都可以与 s[i],s[j]组成一个新的回文串,因此要加上dp[i + 1][j - 1] + 1。
if(s[i] != s[j]) 那么dp[i][j] = dp[i + 1][j] + dp[i][ j - 1] - dp[i + 1][j - 1];
代码:
问有几种删除字符的方法可以使得该字符串为回文。
思路:
记忆化搜索。
状态转移方程:
if(s[i] == s[j]) , 那么 dp[i][j] = dp[i + 1][j] + dp[i][ j - 1] - dp[i + 1][j - 1] + dp[i + 1][j - 1] + 1;
dp[i][j]表示的是从i到j最多可以有几个不同的回文串。 回文串不同那么自然删除的方法就不一样了。
dp[i][j] 是由 i + 1到j的回文串数和i到j - 1的回文串数组成的,然而中间的i + 1到j - 1的回文串多算了一次 因此要减去,但是s[i] == s[j]的时候,i + 1 到j - 1的每个回文串都可以与 s[i],s[j]组成一个新的回文串,因此要加上dp[i + 1][j - 1] + 1。
if(s[i] != s[j]) 那么dp[i][j] = dp[i + 1][j] + dp[i][ j - 1] - dp[i + 1][j - 1];
代码:
#include <iostream> using namespace std; #include <stdio.h> #include <cstring> char s[65]; long long dp[105][105]; bool vis[105][105]; long long d(int i,int j) { long long & ans = dp[i][j]; if(vis[i][j]) return ans; vis[i][j] = 1; if(i > j) ans = 0; else if(i == j) ans = 1; else if(s[i] == s[j]) { ans = d(i,j - 1) + d(i + 1,j) + 1; } else { ans = d(i,j - 1) + d(i + 1, j) - d(i + 1, j - 1); } return ans; } int main() { int n; scanf("%d",&n); getchar(); while(n--) { gets(s); int len =strlen(s); for(int i = 0;i < len; i++) dp[i][i] = 1; memset(vis,0,sizeof(vis)); long long ans = d(0,len - 1); /* for(int i = len - 1; i >= 0; i--) { for(int j = i + 1; j < len; j++) { 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]; if(ans < dp[i][j]) ans = dp[i][j]; } } }*/ printf("%lld\n",ans); } return 0; } 第二种: #include <iostream> using namespace std; #include <stdio.h> #include <cstring> char s[65]; long long dp[105][105]; bool vis[105][105]; /*long long d(int i,int j) { long long & ans = dp[i][j]; if(vis[i][j]) return ans; vis[i][j] = 1; if(i > j) ans = 0; else if(i == j) ans = 1; else if(s[i] == s[j]) { ans = d(i,j - 1) + d(i + 1,j) + 1; } else { ans = d(i,j - 1) + d(i + 1, j) - d(i + 1, j - 1); } return ans; }*/ int main() { int n; scanf("%d",&n); getchar(); while(n--) { gets(s); int len =strlen(s); for(int i = 0;i < len; i++) dp[i][i] = 1; memset(vis,0,sizeof(vis)); // long long ans = d(0,len - 1); // long long ans = 0; for(int i = len - 1; i >= 0; i--) { for(int j = i + 1; j < len; j++) { 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]; // if(ans < dp[i][j]) // ans = dp[i][j]; } } } printf("%lld\n",dp[0][len - 1]); } return 0; }
相关文章推荐
- 截获系统调用(sys_call_table/VFS)
- 表空间使用率
- PASCAL VOC数据集The PASCAL Object Recognition Database Collection
- 《程序员自我修养》第七章读书笔记
- 解决键盘弹起时把UINavigationBar顶出屏幕外面的问题
- FFT(快速傅立叶变换):HDU 1402 A * B Problem Plus
- 51nod 1008 N的阶乘mod P
- 星期几(蓝桥杯)
- % 与 & 操作符
- 王爽老师汇编语言视屏下载
- <<第一行代码>>--全局获取Context技巧
- 如何演示你的App?Android录制Gif动态图教程
- WTF交换
- 算法代码实现之快速排序,Java实现
- ACM做题过程中的一些小技巧
- linux命令 time
- 解释程序和编译程序的区别
- 自适应中值滤波
- 20160229 ADO.NET连接SQL Server数据库(SqlHelper类)
- ionic splash screen 之后出现的白屏解决办法