如果没有任何条件限制,A、B、C、D组成长度为n的字符串,其个数应该为:4n。
因为有了A、C需要出现偶数次的要求,就出现合法和不合法的不同分组。
在不合法的组里,又有
1.A出现奇数次、C出现偶数次;
2.C出现奇数次、A出现偶数次;
3.A出现奇数次、C出现奇数次;
三种情况。
我们用数组
f[n][0]保存长度为n,合法的字符串的个数。
f[n][1]保存长度为n,仅A出现奇数次的字符串的个数。
f[n][2]保存长度为n,仅C出现奇数次的字符串的个数。
f[n][3]保存长度为n,A、C出现奇数次的字符串的个数。
f[n][0]
长度为n-1的合法字符串在末尾加上一个B或者D,都可以变成长度为n的合法字符串。
长度为n-1的仅A出现奇数次的字符串再在末尾加上一个A,也可以变成合法字符串。
长度为n-1的仅C出现奇数次的字符串再在末尾加上一个C,也可以变成合法字符串。
所以,f[n][0]=2×f[n-1][0]+f[n-1][1]+f[n-1][2];
f[n][1]
长度为n-1的合法字符串在末尾加上A,都可以变成长度为n的仅A出现奇数次的字符串。
长度为n-1的仅A出现奇数次的字符串再在末尾加上一个B或者D,也可以变成仅A出现奇数次的字符串。
长度为n-1的A、C出现奇数次的字符串再在末尾加上一个C,也可以变成仅A出现奇数次的字符串。
所以,f[n][1]=2×f[n-1][1]+f[n-1][0]+f[n-1][3];
f[n][2]
长度为n-1的合法字符串在末尾加上C,都可以变成长度为n的仅C出现奇数次的字符串。
长度为n-1的仅C出现奇数次的字符串再在末尾加上一个B或者D,也可以变成仅C出现奇数次的字符串。
长度为n-1的A、C出现奇数次的字符串再在末尾加上一个A,也可以变成仅C出现奇数次的字符串。
所以,f[n][2]=2×f[n-1][2]+f[n-1][0]+f[n-1][3];
f[n][3]
长度为n-1的A、C出现奇数次的字符串在末尾加上一B或者D,都可以变成长度为n的A、C出现奇数次的字符串。
长度为n-1的仅A出现奇数次的字符串再在末尾加上一个C,也可以变成A、C出现奇数次的字符串。
长度为n-1的仅C出现奇数次的字符串再在末尾加上一个A,也可以变成A、C出现奇数次的字符串。
所以,f[n][3]=2×f[n-1][3]+f[n-1][1]+f[n-1][2];
综上所述,我们得到:
f[n][0]=2×f[n-1][0]+f[n-1][1]+f[n-1][2];①
f[n][1]=2×f[n-1][1]+f[n-1][0]+f[n-1][3];②
f[n][2]=2×f[n-1][2]+f[n-1][0]+f[n-1][3];③
f[n][3]=2×f[n-1][3]+f[n-1][1]+f[n-1][2];④
f[1][0]=2
f[1][1]=1
f[1][2]=1
f[1][3]=0
发现f[1][1]与f[1][2]初始状态相同,而且以后迭代方程也相同,所以f[n][1]=f[n][2]
又有f[n][0]+f[n][3]=f[n][1]+f[n][2]
∵f[n][0]+f[n][1]+f[n][2]+f[n][3]=4n
∴f[n][0]+f[n][3]=f[n][1]+f[n][2]=2×4n-1
∴f[n-1][1]+f[n-1][2]=2×4n-2
∴f[n][0]=2×f[n-1][0]+f[n-1][1]+f[n-1][2]=2×f[n-1][0]+2×4n-2
我们得到:
f[n][0]=2×f[n-1][0]+22n-3
f[n-1][0]=2×f[n-2][0]+22n-5
┋
f[n-m][0]=2×f[n-m-1][0]+22n-2m-3
┋
f[2][0]=2×f[1][0]+21
f[1][0]=2
开始一层层往下迭代:
f[n][0]
=2×f[n-1][0]+22n-3
=22×f[n-2][0]+22n-4+22n-3
┋
=2m×f[n-m][0]+22(n-m)-1+m-1+...+22n-3
=2n-1×f[1][0]+2n-1+2n+...+22n-3
f[1][0]=2;
∴f[n][0]=2n+2n-1+2n+...+22n-3=22n-2+2n-1
公式得到了:f(n)=22n-2+2n-1
但就这样直接编程那是不可能实现的,因为n的范围1≤N<264
怎么的范围,是不能求出f(n)的。所以还得找其他规律。
因为题目只要求输出最后2位数,我们依次输出2的n的最后两位看看...
20->1
21->2
22->4
23->8
24->16
25->32
26->64
27->28
28->56
29->12
210->24
211->48
212->96
213->92
214->84
215->68
216->36
217->72
218->44
219->88
220->76
221->52
222->4
__int64n;
intdata[20]={4,8,16,32,64,28,56,12,24,48,96,92,84,68,36,72,44,88,76,52};
intmain(){
intcas,res;
while(scanf("%d",&cas)&&cas!=0){
for(inti=0;i<cas;i++){
scanf("%I64d",&n);
if(n==1){
printf("Case%d:2\n",i+1);
continue;
}
if(n==2){
printf("Case%d:6\n",i+1);
continue;
}
if(n==3){
printf("Case%d:20\n",i+1);
continue;
}
__int64cot,bot;
cot=(n-3)%20;
bot=(2*n-4)%20;
res=data[cot]+data[bot];
printf("Case%d:%I64d\n",i+1,res%100);
}
printf("\n");
}
//system("pause");
return0;
}