题意:
有红黄蓝三张颜色来涂色,连续的三块不能是三种不同的颜色,问涂n块有多少种情况?
思路:
看到题目,显然是递推找规律。
那么就来找吧。
若前两块的颜色相同,那么下一块可以涂三种颜色;如果前两块的颜色不同,那么下一块可以涂两种颜色。
既然这样可容易就能想到开两个数组a,b分别记录 最后两块颜色相同的情况数 和 最后两块颜色不同的情况数。
很显然的,a1 = 3; b1 = 0; an+1 = an + bn; bn+1 = 2*an + bn;
最终的答案就是 an+bn
那么题目这样就做完了。
后来看discuss发现了另一种递推式,最后再说。
AC代码如下:
//2569.cpp
#include <iostream>
#define maxn 50
int a[maxn],b[maxn];
using namespace std;
int main()
{
int T,i,n;
cin >> T;
a[1] = 3; b[1] = 0;
for (i=2;i<40;++i)
{
a[i] = a[i-1]+b[i-1];
b[i] = a[i-1]*2+b[i-1];
}
while (T--)
{
cin >> n;
cout << a[n]+b[n] << endl;
}
return 0;
}
还有一种递推式是就总情况数本身f来考虑,很显然大体想法是一致的,都是要分成最后两块相同的和最后两块不同的。
在n-1块中,若最后两块相同,那么这一部分的情况数和n-2块的情况数是相通的,所以这一块是 f[n-2] 种;每一种都可以配三种颜色,故为 f[n-2]*3 种。
若最后两块不同,由上分析得,有 f[n-1]-f[n-2] 种;每一种都可以配两种颜色,故为 (f[n-1]-f[n-2])*2 种。
加起来也就是 f[n] = 2*f[n-1]+f[n-2];
这种思路感觉也很好,是把我一开始的想法延续了下去。将前两块颜色相同和颜色不同的情况数直接用 f 来表示。