【CF】Day73——Codeforces Round 887 (Div. 2) B (思维 + 模拟)
B. Fibonaccharsis
题目:
思路:
比C题有意思,但也么意思
对于这一题我们可以考虑最小的情况,即 f0 = 0,f1 =1 时,然后看看什么时候会超过 n 的最大值,我们可以发现 k > 30 时就炸了,所以如果 k > 30 就可以直接输出 0
然后我们讨论 k <= 30 的情况即可,我们发现如果正向考虑是很难的,所以我们反向考虑
我们既然知道最后一位,那我们尝试枚举前一位是什么,其范围一定在 0 ~ n 中,然后根据公式我们直接一个一个往前枚举即可,只要有某一位小于 0,那么就不行,否则最后一定满足 a[0] >= 0,此时我们取这个即可,时间复杂度最坏为 n*30 可以过
代码:
#include <iostream>
#include <algorithm>
#include<cstring>
#include<cctype>
#include<string>
#include <set>
#include <vector>
#include <cmath>
#include <queue>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <stack>
#include <memory>
using namespace std;
#define int long long
#define yes cout << "Yes\n"
#define no cout << "No\n"void solve()
{int n, k;cin >> n >> k;if (k >= 30){cout << "0\n";return;}int cnt = 0;vector<int> f(31, 0);f[k] = n;int flag = 0;auto dfs = [&](auto self,int dep) ->void{if (dep < 0){return;}f[dep] = f[dep + 2] - f[dep + 1];if (f[dep] < 0){flag = 0;return;}self(self, dep - 1);};for (int i = 0; i <= n; i++){flag = 1;f[k - 1] = i;dfs(dfs, k - 2);cnt += flag;}cout << cnt << endl;
}signed main()
{cin.tie(0)->sync_with_stdio(false);int t = 1;cin >> t;while (t--){solve();}return 0;
}