题目目录
第一题 交互题
题意
一句话题意:求把$n$拆成一些不同的斐波那契数之和的方案数。
$n\leq 10^{18}$。
题解
此题在洛谷上有原题。若想看详细题解,请转到这里。
我们可以把$n$贪心拆为几个斐波那契数之和,然后对于每一个数,我们$dp_{i0}$和$dp_{i1}$表示$1-i$的数中$i$取或不取所能得到的方案数,然后答案就是$dp_{n0}+dp_{n1}$了。
附上代码:
#include <bits/stdc++.h>
#pragma GCC optimize("Ofast", "stack-protector-explicit")
using namespace std;
#define int long long
int rd() {
int ret=0;char ch;
while(!isdigit(ch=getchar()));
ret=ch-'0';while(isdigit(ch=getchar()))ret=ret*10+ch-'0';
return ret;
}
void wd(int x) {
printf("%lld\n",x);
}
int F[87]; int dp[87][2];
int T,n;
vector<int> A;
inline int R(int n) {
A.clear();
for (int i=86; i; i--) if (n >= F[i]) {
A.push_back(i); n -= F[i];
}
sort(A.begin(), A.end());
dp[0][0] = (A[0]-1)/2; dp[0][1] = 1;
for (int i=1; i<A.size(); i++) {
dp[i][1] = dp[i-1][0] + dp[i-1][1];
dp[i][0] = dp[i-1][1] * ((A[i]-A[i-1]-1)/2) + dp[i-1][0] * ((A[i]-A[i-1])/2);
}
return dp[A.size()-1][0] + dp[A.size()-1][1];
}
signed main() {
F[1] = 1; F[2] = 2;
for (int i=3; i<=86; i++) F[i] = F[i-1] + F[i-2];
T = rd();
while (T--) {
n = rd();
wd(R(n));
}
return 0;
}
第三题 传统题(提交答案)
题意
一句话题意:每组数据给你小样例和大输入,让你求大输出。(都是数据结构的操作)