Byfibonacci 动态规划

链接:https://ac.nowcoder.com/acm/contest/33467/B
来源:牛客网

动态规划

预处理出前40位斐波那契数列,然后挨个考虑每个斐波那契对数列的贡献,背包问题,注意常数的优化。

#pragma GCC optimize(3,"Ofast","inline")
// O3优化
#include <bits/stdc++.h>
using namespace std;

#define endl '\n'
#define int long long
#define fi first
#define se second
#define pb push_back

#define foa(x, y, z) for(int x = (y), ooo = (z); x <= z; ++x)
#define fos(x, y, z) for(int x = (y), ooo = (z); x >= z; --x)
#define ckmax(x, y) ((x) < (y) ? (x) = (y), 1 : 0)
#define ckmin(x, y) ((x) > (y) ? (x) = (y), 1 : 0)

typedef pair<int, int> pii;
typedef long long ll;
const int mod = 998244353;
const int inf = 0x3f3f3f3f3f3f3f3f;
const int N = 1e7 + 1000;
int n, m;
int a[N], f[N], st[N];
void inc(int &x, int y)
{
    x = ((x + y) % mod + mod) % mod;
}
void init()
{
	a[0] = 1, a[1] = 1;
    f[0] = 1;
    int end = 0;
    foa(i, 0, 1e6) {
        if(i >= 2) a[i] = a[i - 1] + a[i - 2];
        if(a[i] > 1e7 + 10) break;
        st[a[i]] = 1;
        end += a[i];
        ckmin(end, 1e7 + 10);
        fos(j, end, a[i]) {
            inc(f[j], a[i] * f[j - a[i]]);
        }
//         if(i <= 2) printf("%d %d %d\n", f[0], f[1], f[2]);
    }
//     foa(n, 100, 200) {
//         int res = f[n] - st[n] * n;
//         inc(res, 0);
//     //     printf("%d %d %d\n", n, f[n], st[n]);
//         if(n == 1) res = 0;
//         cout << res << endl;
//     }
}
void solve()
{
    cin >> n;
    int res = f[n];
    inc(res, 0);
//     printf("%d %d %d\n", n, f[n], st[n]);
//     if(n == 1) res = 0;
    cout << res << endl;
}
signed main()
{
	ios::sync_with_stdio(false); cin.tie(0); cout.tie(0);
    init();
    int t;
    cin >> t;
    while(t--)
	solve();
    return 0;
}
posted @ 2022-04-26 21:33  1564269628  阅读(50)  评论(0)    收藏  举报