先dp打表
#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
LL s[50];
int dp[10][20000];
int main()
{
s[0]=0;
s[1]=1;
for(int i=2;i<=15;i++){
s[i]=s[i-1]+s[i-2];
}
// for(int i=0;i<10;i++){
// cout<<s[i]<<" ";
// }
// cout<<endl;
dp[0][0]=1;
for(int num=1;num<=10;num++){
for(int val=1000;val>=0;val--){
for(int k=0;k<=15;k++){
dp[num][val+s[k]]|=dp[num-1][val];
// if(dp[num][val+s[k]]){
// cout<<val+s[k]<<endl;
// }
}
}
}
for(int i=1;i<=10;i++){
for(int j=0;j<=1500;j++){
if(!dp[i][j]){
cout<<i<<" "<<j<<endl;
break;
}
}
}
return 0;
}
再使用高斯消元+完全主元素+若尔当方法
//高斯消元+完全主元素+若尔当方法
#include<bits/stdc++.h>
using namespace std;
int n;
double a[10][10];//对应的增广矩阵
double ans[10];//对应的答案
//交换行
void swap_r(int q,int p)
{
for(int i=1;i<=n+1;i++){
double t=a[p][i];
a[p][i]=a[q][i];
a[q][i]=t;
}
}
//交换列
void swap_c(int q,int p)
{
for(int i=1;i<=n+1;i++){
double t=a[i][p];
a[i][p]=a[i][q];
a[i][q]=t;
}
}
void prt()
{
for(int i=1;i<=n+1;i++){
for(int j=1;j<=n+1;j++){
printf("%2.5f ",a[i][j]);
}
printf("\n");
}
printf("\n");
}
void gs()
{
for(int i=1;i<n;i++){
//找出i i位置对应最大的主元素
double m=fabs(a[i][i]);
int p=i,q=i;
for(int j=i+1;j<=n;j++){
for(int k=i;k<=n;k++){
if(fabs(a[j][k])>m){
m=fabs(a[j][k]);
p=j;
q=k;
}
}
}
if(p!=i){
swap_r(p,i);
printf("交换%d与%d行\n",p,i);
}
if(q!=i){
swap_c(q,i);
printf("交换%d与%d列\n",q,i);
}
prt();
//把i i位置下面的进行消元
printf("进行消元\n");
for(int j=i+1;j<=n;j++){
if(a[i][j]==0.0){
continue;
}
double t=a[j][i]/a[i][i];
a[j][i]=0.0;
for(int k=i+1;k<=n+1;k++){
a[j][k]-=t*a[i][k];
}
}
prt();
}
}//此时已经换为了一个上三角形
//进行行标准型的变换
void red()
{
for(int i=n;i>1;i--){
printf("%d %d位置上方进行消元\n",i,i);
for(int j=i-1;j>=1;j--){
if(a[j][i]==0){
continue;
}
double t=a[j][i]/a[i][i];
a[j][i]=0.0;
//因为i左列的不必处理,因为i这行左边都为0
for(int k=i+1;k<=n+1;k++){
a[j][k]-=t*a[i][k];
}
}
prt();
}
}
int main()
{
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=1;j<=n+1;j++){
scanf("%lf",&a[i][j]);
}
}
//在下面增加一行1 2 3 4 0,此处在后面消元中作用大
//这个下面加了这一行最后 答案进行处理,使得矩阵既可以进行行变换也可以进行列变换
for(int i=1;i<=n;i++){
a[n+1][i]=i;
}
for(int i=1;i<=n+1;i++){
for(int j=1;j<=n+1;j++){
printf("%f ",a[i][j]);
}
printf("\n");
}
printf("\n");
gs();
red();
for(int i=1;i<=n;i++){
ans[(int)a[n+1][i]]=a[i][n+1]/a[i][i];
}
for(int i=1;i<=n;i++){
printf("x%d = %f\n",i,ans[i]);
}
return 0;
}
最后再使用矩阵快速幂
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const ll MOD=998244353;
const int N=4;
struct node
{
ll a[10][10];
};
node shu,ans,mp;
//shu是输入的矩阵,ans是所求答案
node matrix(node x,node y)
{
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++){
mp.a[i][j]=0;
for(int p=1;p<=N;p++)
mp.a[i][j]=(mp.a[i][j]+x.a[i][p]*y.a[p][j]+MOD)%MOD;
//矩阵乘法
}
return mp;
}
void work(ll k)
{
//矩阵快速幂
for(int i=1;i<=N;i++)
for(int j=1;j<=N;j++)
ans.a[i][j]=0;
for(int i=1;i<=N;i++) ans.a[i][i]=1;
node t=shu;
while(k){
if(k&1)
ans=matrix(ans,t);
k>>=1;
t=matrix(t,t);
}
}
int main()
{
ll n;
for(int i=1;i<=N;i++){
for(int j=1;j<=N;j++){
shu.a[i][j]=0;
}
}
shu.a[1][1]=4;
shu.a[1][2]=-4;
shu.a[1][3]=1;
shu.a[2][1]=1;
shu.a[3][2]=1;
while(cin>>n)
{
if(n==1) printf("4\n");
else if(n==2) printf("12\n");
else if(n==3) printf("33\n");
else
{
work(n-3);
printf("%lld\n",(ans.a[1][1]*33%MOD+ans.a[1][2]*12%MOD+ans.a[1][3]*4%MOD)%MOD);
}
}
return 0;
}