网易编程题(二)

来源:互联网 发布:淘宝淘词助手官网 编辑:程序博客网 时间:2024/06/17 18:06
一个只包含'A'、'B'和'C'的字符串,如果存在某一段长度为3的连续子串中恰好'A'、'B'和'C'各有一个,那么这个字符串就是纯净的,否则这个字符串就是暗黑的。例如:
BAACAACCBAAA 连续子串"CBA"中包含了'A','B','C'各一个,所以是纯净的字符串
AABBCCAABB 不存在一个长度为3的连续子串包含'A','B','C',所以是暗黑的字符串

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

分析:

动态规划思想:

要知道长度为n的字符串的黑暗字符串数 f(n),联想到在长度为n-1的黑暗字符串后面追加字母 ‘A’ 'B' 'C',考虑到n-1长度的暗黑字符串其尾部三位字符,肯定不全含A B C,所以最后两位字符可相同 也可不同,分两种情况:

f(n) = s(n) + d(n) ,s(n)表示n长度黑暗串后两位相同的黑暗字符串数,d(n)表示后两位不同时的情况。

(1)假设n-1长度有s(n-1)个后两位相同,则可以构造处 3*s(n-1)

比如:BAA  可构造出 BAAA BAAB BAAC

(2)假设n-1长度有d(n-1)个后两位相同,则可以构造处 2*d(n-1)

比如:BAB  可构造出 BABA BABB

所以 f(n) = s(n) + d(n) =3s(n-1) + 2d(n-1) =2f(n-1) + s(n-1),有个s(n-1)未消掉,联想到找f(n-2)和s(n-1)的关系

注意到(1)中 构造出来的有1/3后两位相同,(2)中有1/2相同

所以 s(n) = s(n-1) + d(n-1) d(n) = 2s(n-1) + d(n-1)

所以 s(n) = f(n-1)

所以 s(n-1)  = f(n-2)


得到: f(n)=2f(n-1) + f(n-2).


代码:

#include<iostream>
using namespace std;
int main()
    {
    int n;
    cin>>n;
    long long  d0 = 3;
    long  d1 = 9;
    long long temp;
    if(n == 1)
        cout<<d0;
    else
        if(n == 2)
        cout<<d1;
    else
        {
        for(int i=3;i<=n;i++)
            {
            temp =d1;
            d1 = 2*d1 + d0;
            d0 = temp;
        }
        cout<<d1;
    }
}




原创粉丝点击