参考链接:https://www.cnblogs.com/JSONBEAN/p/6433755.html
题目描述:
一个只包含'A'、'B'和'C'的字符串,如果存在某一段长度为3的连续子串中恰好'A'、'B'和'C'各有一个,那么这个字符串就是纯净的,否则这个字符串就是暗黑的。例如:
BAACAACCBAAA 连续子串"CBA"中包含了'A','B','C'各一个,所以是纯净的字符串;AABBCCAABB 不存在一个长度为3的连续子串包含'A','B','C',所以是暗黑的字符串;
你的任务就是计算出长度为n的字符串(只包含'A'、'B'和'C'),有多少个是暗黑的字符串;
输入描述:
输入一个整数n,表示字符串的长度(1≤n≤30);
输出描述:
给出一个整数表示有多少个暗黑字符串
输入例子:
2
3
输出例子:
9
21
解题思路:
采用动态规划的思想,动态规划一般的状态转移方程为:
f(n)=k*f(n-1)+m*(f-2)+n*f(n-3)+...+d*f(0)
按照动态规划的结题思想,f(n)的解一般和f(n-1)的解相关,在本题中,从最后一位(n)向前扩展一位(n-1位),如果这两位字符串的值相同时的暗黑字符串的数量记为S(n),不同时记为D(n),则n位字符串的暗黑字符串的数量为 f(n)=S(n)+D(n);
对于第n为来说,n-1位和n-2位字符串的值只有相同S(n-1)和不同D(n-1)两种情况。所以
对于最后位置字符相同来说,如果n-1和n-2相同如AA,则n位位置只能为A一种情况;如果n-1和n-2不同如AB则n位置也只有一种选择即B和n-1位相同的值。所以S(n)=S(n-1)+D(n-1)
对于最后位置字符不同来说,如果n-1和n-2相同如AA,则n位位置有两种情况B或C;如果n-1和n-2不同如AB则n位置也只有一种选择即和n-2位的值A。所以D(n)=2S(n-1)+D(n-1)
由
f(n)=S(n)+D(n);
S(n) = S(n-1)+D(n-1);
D(n)=2S(n-1)+D(n-1);
由第一个和第二个公式可得:f(n-1)=S(n)
三个公式可以得到 f(n)=f(n-1)+D(n)=f(n-1)+2S(n-1)+D(n-1)=2f(n-1)+S(n-1)=2f(n-1)+S(n-2)+D(n-2)=2f(n-1)+f(n-2)
得到状态转移方程之后,进行编码
static long Diabo(int n){
long res=-1;
long[] dp = new long[n+1];
if (n>=1){
dp[0]=0;
dp[1]=3;
}
if(n>=2){
dp[2]=9;
for (int i=3;i<=n;i++){
dp[i]=2*dp[i-1]+dp[i-2];
}
}
res =dp[n];
return res;
}