HDU 6198 2017沈阳网络赛 线形递推

Posted Lsxxxxxxxxxxxxx

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU 6198 2017沈阳网络赛 线形递推相关的知识,希望对你有一定的参考价值。

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6198

题意:给出一个数k,问用k个斐波那契数相加,得不到的数最小是几。

解法:先暴力打表看看有没有规律。

#include <bits/stdc++.h>
using namespace std;
int dp[2000][2000];
typedef long long LL;
int main()
{
    LL c[50];
    c[0]=0;
    c[1]=1;
    c[2]=1;
    for(int i=2; i<50; i++) c[i] = c[i-1]+c[i-2];
    dp[0][0]=1;
    for(int i=0; i<=40; i++){
        for(int j=1; j<=40; j++){
            for(int k=c[i]; k<=1000; k++){
                dp[j][k] = dp[j][k] + dp[j-1][k-c[i]];
            }
        }
    }
    for(int i=1; i<=40; i++)
        for(int j=1; j<=1000; j++)
    if(dp[i][j]==0){
        printf("%d\n", j);
        break;
    }
}

 然后发现这恰好是一个线形递推,递推式就是dp[n]=dp[n-1]*3-dp[n-2]+1。

#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
const int mod = 998244353;
struct Matrix{
    LL a[3][3];
    void set1(){
        memset(a, 0, sizeof(a));
    }
    void set2(){
        set1();
        for(int i=0; i<3; i++) a[i][i]=1;
    }
    void set3(){
        a[0][0]=3,a[0][1]=-1,a[0][2]=1;
        a[1][0]=1,a[1][1]=0,a[1][2]=0;
        a[2][0]=0,a[2][1]=0,a[2][2]=1;
    }
    void set4(){
        set1();
        a[0][0]=12;
        a[1][0]=4;
        a[2][0]=1;
    }
};
Matrix operator*(const Matrix &a, const Matrix &b){
    Matrix res;
    res.set1();
    for(int i=0; i<3; i++){
        for(int j=0; j<3; j++){
            for(int k=0; k<3; k++){
                res.a[i][j] = (res.a[i][j]+a.a[i][k]*b.a[k][j]+mod)%mod;
            }
        }
    }
    return res;
}
Matrix qsm(Matrix a, int n){
    Matrix res;
    res.set2();
    while(n){
        if(n&1) res=res*a;
        a=a*a;
        n/=2;
    }
    return res;
}
int main()
{
    int n;
    while(scanf("%d", &n)!=EOF)
    {
        if(n==1) printf("4\n");
        else if(n==2) puts("12");
        else{
            Matrix a,b;
            a.set3();
            b.set4();
            a = qsm(a,n-2);
            a=a*b;
            printf("%lld\n", (a.a[0][0]+mod)%mod);
        }
    }
    return 0;
}

 

以上是关于HDU 6198 2017沈阳网络赛 线形递推的主要内容,如果未能解决你的问题,请参考以下文章

HDU 6205 2017沈阳网络赛 思维题

HDU 6200 2017沈阳网络赛 树上区间更新,求和

2017ICPC沈阳网络赛 HDU 6025 -- card card card(最大子段和)

HDU 6201 2017沈阳网络赛 树形DP或者SPFA最长路

HDU 6197 array array array 2017沈阳网络赛 LIS

hdu 5901 Count primes (2016沈阳网络赛)