递推复习(3)
偶数个3
Desciption
编程求出所有的 n 位数中,有多少个数中有偶数个数字 3。
Input
一行一个正整数 n,0<n<1000。
Output
一行一个正整数,表示 n 位数中有多少个数有偶数个 3。最后答案为12345取模
Sample Input
2
Sample Output
73
Analysis
这一道题的话你要记录两个,奇数有多少个,偶数有多少个。最后实际上经过大量的数据来进行运算(WYX大佬与我一起进行的),我们发现了规律实际上因为我们最开始把1位数那里的偶数个数量设置为9,所以得出来的式子很复杂。
实际就这么想:
偶数个三,再取一位有9个选择,再加上奇数个三,最后只可以取三,1个选择,所以式子就比较明了了
Code
#include<bits/stdc++.h>
#define maxi 1007
#define Mod 12345
using namespace std;
int f[maxi][2];
/*
*后面的,0表示奇数,1表示偶数
*/
int n;
int main(){
scanf("%d",&n);
f[1][1]=8;f[1][0]=1;
for(int i=2;i<=n;i++){
f[i][0]=(9*f[i-1][0]+f[i-1][1])%Mod;
f[i][1]=(9*f[i-1][1]+f[i-1][0])%Mod;
}
cout<<f[n][1];
}
斐波那契前N项和
**Desctiption
求斐波那契数列前n项和取模m
Input
一行两个整数n m
Outpuw
输出前n项和取模m
Sample Input
5 100
Sample Output
12
Analysis
因为数据范围很大,我在这没有给出,但是很明确地,要用long long
以及矩阵快速幂,考虑构造的矩阵为
\[\begin{bmatrix}
1 &0 & 0\\
1 &1 & 1\\
1& 1 & 0
\end{bmatrix}
\]
而另外一个矩阵则是
\[\begin{bmatrix}
2 &1 &1\\
\end{bmatrix}
\]
这是他们初始的状态,解释一下,下面的矩阵第一个数就是我们要求的答案,第二个数就是此时的斐波拉契数,第三个则是前面的一个斐波拉契数
因此可以得到代码
Code
#include<bits/stdc++.h>
#define Int64 long long
using namespace std;
Int64 A[3][3];
Int64 mod,n;
void mul(Int64 *f,Int64 (*t)[3]){
Int64 tmp[3];
memset(tmp,0,sizeof(tmp));
for(int i=0;i<=2;i++){
for(int k=0;k<=2;k++){
(tmp[i]+=f[k]*t[k][i])%=mod;
}
}
for(int i=0;i<=2;i++)f[i]=tmp[i];
return ;
}
void mulsel(Int64 (*f)[3]){
Int64 tmp[3][3];
memset(tmp,0,sizeof(tmp));
for(int i=0;i<=2;i++){
for(int j=0;j<=2;j++){
for(int k=0;k<=2;k++){
(tmp[i][j]+=f[i][k]*f[k][j])%=mod;
}
}
}
for(int i=0;i<=2;i++){
for(int j=0;j<=2;j++)f[i][j]=tmp[i][j];
}
return;
}
void qkpow(Int64 b){
Int64 ans[3]={2,1,1};
while(b){
if(b&1){
mul(ans,A);
}
mulsel(A);
b>>=1;
}
printf("%lld",ans[0]);
}
int main(){
scanf("%lld%lld",&n,&mod);
A[0][0]=1;A[0][1]=0;A[0][2]=0;
A[1][1]=1;A[1][0]=1;A[1][2]=1;
A[2][0]=1;A[2][1]=1;A[2][2]=0;
if(n==1)cout<<1;
else if(n==2)cout<<2;
else qkpow(n-2);
return 0;
}
我不求被他人理解,被理解类似于自我卖淫