暗黑的字符串

题目描述

一个只包含'A'、'B'和'C'的字符串,如果存在某一段长度为3的连续子串中恰好'A'、'B'和'C'各有一个,那么这个字符串就是纯净的,否则这个字符串就是暗黑的。例如:
BAACAACCBAAA 连续子串"CBA"中包含了'A','B','C'各一个,所以是纯净的字符串
AABBCCAABB 不存在一个长度为3的连续子串包含'A','B','C',所以是暗黑的字符串

你的任务就是计算出长度为n的字符串(只包含'A'、'B'和'C'),有多少个是暗黑的字符串。


本题思路:

本题是典型的动态规划的问题,求f(n)与f(n-1)的关系的。

经发现,f(n)只与f(n-1)的最后两个字符有关,如果f(n-1)的最后两个字符相等,那么用输入ABC都可以得到f(n),如果f(n-1)的最后两个字符不等,那么只能输入和这两个字符一样的字符,比如AB我就只能在最后输入A或者B。

所以设f(n-1)由两部分组成,一部分是s(n-1),表示最后两个字符相等的所有集合的个数,一部分是d(n-1),表示最后两个字符不相等的所有集合的个数。

所以f(n)=3S(n-1)+2D(n-1)=2f(n)+S(n-1)

又由s(n-1)和d(n-1)推导s(n)和d(n),发现s(n-1)推导后的结果有1/3的结果是最后两个字符串相同的,比如AA有AAA,AAB,AAC;而d(n-1)推导后的结果有1/2的结果是最后两个字符串相同的,比如AB有ABA,ABB。

所以得到s(n)=s(n-1)+d(n-1)=f(n-1)

所以f(n)=2*f(n-1)+f(n-2)

代码如下:

 <?php
$handler = fopen('php://stdin', 'r');
$n =  trim(fgets($handler));
echo cal($n);
function cal($n) {
    //动态规划
    if ($n == 1) return 3;
    if ($n == 2) return 9;
    $res = 2*cal($n-1) + cal($n-2); 
    return $res;
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值