涉及知识点:枚举,
STL
。
题目大意
给你一个序列,让你选出一些元素,使其构成 fibonacccccci
数列,求数列的最大长度。
解题思路
定义一个桶,$mp_i$ 代表 $i$ 这个数在输入序列当中出现的次数。
由于 $n \le 1000$,所以可以直接暴力枚举 fibonacccccci
数列的前两个数。
前两个数固定了,这个序列的所有数字都固定了,只需要判断当前序列的下一个数字可不可以组合出来。
map<int, int> hh;
int cnt = 2;
int now1 = a[i];
int now2 = a[j];
hh[now1]++, hh[now2]++;
while (hh[now1 + now2] < mp[now1 + now2]) {
int t = now1;
now1 = now2;
now2 = t + now2;
hh[now2]++;
cnt++;
}
再来说一下剪枝。
- 如果序列里包含 $0$,先把 $ans$ 初始化成 $0$ 的个数,这样就可以防止枚举起点的多余计算。
- 如果序列包含两个及以上个 $0$,需要在枚举前两个数时特判,因为起始两个 $0$ 的序列全是 $0$,会在第 $1$ 种剪枝当中直接计算出来最优解。
- 如果前一个序列的第 $1$ 个数和这个序列的第 $1$ 个数相同,说明两个序列是完全一样的,直接跳过当前序列,计算下一个序列。
最后,统计每个序列长度,取最大值即可。
代码
#include <bits/stdc++.h>
#define int long long
#define endl '\n'
#define il inline
using namespace std;
const int N = 1000 + 10;
int n, a[N];
map<int, int> mp;
int ans;
vector<int> v;
il void Init() {
cin >> n;
for (int i = 1; i <= n; i ++ ) cin >> a[i];
}
il void Solve() {
for (int i = 1; i <= n; i ++ ) mp[a[i]]++;//统计数字出现个数
ans = max(ans, mp[0]);//剪枝1
sort(a + 1, a + n + 1);
for (int i = 1; i <= n; i ++ )
for (int j = 1; j <= n; j ++ ) {
if (i == j) continue;//起始不能为同一个位置的数
if (a[i] == 0 && a[j] == 0) continue;//剪枝2
if (i > 1 && a[i - 1] == a[i]) break;//剪枝3
map<int, int> hh;//统计当前序列数字出现的个数
int cnt = 2;
int now1 = a[i];
int now2 = a[j];
hh[now1]++, hh[now2]++;
while (hh[now1 + now2] < mp[now1 + now2]) {
int t = now1;
now1 = now2;
now2 = t + now2;
hh[now2]++;
cnt++;//统计当前序列长度
}
ans = max(ans, cnt);//更新答案
}
cout << ans;
}
signed main() {
ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
// freopen("fibonacci.in", "r", stdin);
// freopen("fibonacci.out", "w", stdout);
int T = 1;
// cin >> T;
while (T--) {
Init();
Solve();
}
}
通过记录。
标签:int,题解,now1,++,hh,ish,序列,CF633D,now2 From: https://www.cnblogs.com/zla2012/p/18502064