zoj 2744 Palindromes

//这题主要是找回文字符串的个数,可以用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;
//}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值