题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6198
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)

Problem Description

We define a sequence HDU - number number number(矩阵快速幂)_# 数学几何:

HDU - number number number(矩阵快速幂)_# 递推_02
HDU - number number number(矩阵快速幂)_# 数学几何_03

Give you an integer HDU - number number number(矩阵快速幂)_# 数学几何_04, if a positive number HDU - number number number(矩阵快速幂)_矩阵快速幂_05 can be expressed by
HDU - number number number(矩阵快速幂)_# 数学几何_06 where HDU - number number number(矩阵快速幂)_# 数学几何_07, this positive number is HDU - number number number(矩阵快速幂)_矩阵快速幂_08. Otherwise, this positive number is HDU - number number number(矩阵快速幂)_ACM题解_09.
Now, give you an integer HDU - number number number(矩阵快速幂)_# 数学几何_04, you task is to find the minimal positive HDU - number number number(矩阵快速幂)_ACM题解_09 number.
The answer may be too large. Please print the answer modulo 998244353.

Input

There are about 500 test cases, end up with EOF.
Each test case includes an integer HDU - number number number(矩阵快速幂)_# 数学几何_04 which is described above. (HDU - number number number(矩阵快速幂)_矩阵快速幂_13)

Output

For each case, output the minimal HDU - number number number(矩阵快速幂)_ACM题解_09 number mod 998244353.

Sample Input

1

Sample Output

4

Problem solving report:

Description: 给你一段斐波那契数列,有个关于mif-good的定义,就是给你一个k,如果对于一个n,能由k项斐波那契数相加来表示,那么这个数就叫mif-good,否则就是mif-bad,现在输入k,让你求最小的mif-bad.
Problem solving: 我们令G(k)表示上述表达的最小的mif-bad数,通过打表我们可以发现G(n)-G(n-1)=F(2n+2),那么我们就可以通过求前缀和求出G(n):

HDU - number number number(矩阵快速幂)_ACM题解_15
对上式相加可得到:
HDU - number number number(矩阵快速幂)_# 数据结构_16
HDU - number number number(矩阵快速幂)_ACM题解_17
故我们只需要求出F(2*n+3)-1就行了。因为数据过大我们需要矩阵加速。

Accepted Code:

/* 
 * @Author: lzyws739307453 
 * @Language: C++ 
 */
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int MOD = 998244353;
struct Mat {
    ll m[3][3];
    Mat() {
        memset(m, 0, sizeof(m));
    }
}ans, a;
Mat Mul(Mat a, Mat b) {
    Mat c;
    for (int i = 0; i < 2; i++)
        for (int j = 0; j < 2; j++)
            for (int k = 0; k < 2; k++)
                c.m[i][j] = (c.m[i][j] + (a.m[i][k] * b.m[k][j]) % MOD) % MOD;
    return c;
}
Mat power(Mat a, int k) {
    Mat p;
    p.m[0][0] = 1, p.m[1][1] = 1;
    while (k) {
        if (k & 1)
            p = Mul(p, a);
        a = Mul(a, a);
        k >>= 1;
    }
    return p;
}
int main() {
    int n;
    while (~scanf("%d", &n)) {
        int k = 2 * n + 3;
        a.m[0][0] = 1, a.m[0][1] = 1;
        a.m[1][0] = 1, a.m[1][1] = 0;
        ans.m[0][0] = 1, ans.m[0][1] = 0;
        ans = Mul(ans, power(a, k - 1));
        printf("%lld\n", (ans.m[0][0] - 1 + MOD) % MOD);
    }
    return 0;
}

打表Code:

/* 
 * @Author: lzyws739307453 
 * @Language: C++ 
 */
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
ll F[1005];
int dp[200][2005];
int main() {
    F[0] = 0, F[1] = 1, F[2] = 1;
    for (int i = 2; i < 1000; i++)
        F[i] = F[i - 1] + F[i - 2];
    memset(dp, 0, sizeof(dp));
    dp[0][0] = 1;
    for (int i = 0; i <= 45; i++)//枚举总类
        for (int j = 1; j <= 50; j++) //枚举个数
            for (ll k = F[i]; k <= 1000; k++) //枚举容量
                dp[j][k] += dp[j - 1][k - F[i]];
    for (int i = 0; i <= 40; i++)
        for (int j = 1; j <= 1000; j++)
            if (!dp[i][j]) {
                printf("%d %d\n", i, j);
                break;
            }
    printf("**************\n");
    for (int i = 0; i < 20; i++)
        printf("%d %d\n", i, F[i]);
    return 0;
}