//这题主要是找回文字符串的个数,可以用DP来做(贴一下别人的代码,学习学习),也可以用分治方法做!
//下面是参照别人的代码再自己实现的,因为之前接触的比较少,所以还不是很熟悉这些题的做法!
//希望可以学到东西!
#include "iostream"
#include "string"
using namespace std;
string s;
int len, count;
void is_palindromes(int i, int j)
{
if (s[i] == s[j])
{
count++;
while (--i >= 0 && ++j < len)
{
if (s[i] == s[j])
count++;
else
return;
}
}
}
int main()
{
int i, j;
while (cin >> s)
{
len = s.length();
count = 0;
for (i = 1; i <= 2; i++)//分两种情况来查找是否有回文字符串,一种是相邻,一种是间隔!
for (j = 0; j < len-i; j++)
{
is_palindromes(j, j+i);
}
count += len;//单个字符也是回文字符串,所以需要加上原来字符串的长度!
cout << count << endl;
s.clear();
}
}
//下面是DP的做法!
/*
首先说下DP方法,其实碰到这种具有很多重复计算的子问题的问题,很容易想到动态规划DP。
对于这个问题可以这样理解:每次都从下标0开始搜索长度依次为2、3、……、n的子串,
长度为1的子串肯定是回文。所以可以设立数组bool dp[n][n],其中dp[i][i]=true,
dp[i][j]表示字符串中从i到j的子串是否是回文,这样对于上面的搜索过程,要判断str[i-j]要是否回文,
可以分为两种情况:
1. i和j之间没有其它字符,所以只要str[i]==str[j]即可。
2. i和j之间还有其它的字符,则要求str[i]==str[j]并且dp[i+1][j-1]=true。
这也很好理解,从i+1到j-1的子串是回文,再两端加上相同的字符,肯定也是回文。
*/
//#include <cstdio>
//#include <cstdlib>
//#include <iostream>
//#include <cstring>
//using namespace std;
//
//char s[5001];
//bool dp[5001][5001];
//
//int main(void)
//{
// int i, j;
// int len;
// int cnt;
// int k;
// while(gets(s))
// {
// len = strlen(s);
// cnt = len;
// for (i = 0; i < len; ++i)
// {
// dp[i][i] = 0;
// }
// for (i = 1; i < len; ++i)
// {
// for (j = 0; j < len-i; ++j)
// {
// k = i+j;
// dp[j][k] = false;
// if (s[j] == s[k])
// {
// if (j+1 < k-1)
// {
// if (dp[j+1][k-1])
// {
// dp[j][k] = true;
// ++cnt;
// }
// }
// else
// {
// dp[j][k] = true;
// ++cnt;
// }
// }
// }
// }
// printf("%d\n", cnt);
// }
// return 0;
//}
zoj 2744 Palindromes
最新推荐文章于 2018-08-19 14:11:58 发布