1 条题解
-
1徐静雨 (xujingyu) LV 8 @ 2023-2-25 11:22:15
本题是要在序列中寻找一个区间,区间内元素不重复,且长度为全局最长。❄
结合线性动规思想,记录以每一项为终点的最长区间的起始位置。因此,每一项元素要通过结构体记录雪花的类别,以及该类别。在此之前最后出现的位置。遍历每一项,通过哈希表的构建查询当前项类别的雪花是否存在,无则插入,有则相应修改该类别的末尾位置信息,通过末尾信息逐项更新的值,求出区间长度,全局判断求最大值。
动规:
-
定义状态变量:表示以i结尾符合条件的区间头
-
状态转移方程: 我们定义为当前雪花,因为只需查询区间内是否有元素与重复 所以,当区间内有元素与相同时,,否则为
也就是。
哈希表:
哈希表可以用更少的时间和空间来查找元素,在此以vector动态数组来实现。又因为是结合动规来实现,查找时需要返回下标,所以用结构体存。
struct node { int x, k; //x为节点值,k为动规循环下标 }; vector <node> h[1000001];
插入函数:
void insert(int x,int i) { h[x % mod].push_back((node){x,i}); }
查询函数(注意返回值):
int find(int x,int i) { int k = 0; for(int j = 0;j < h[x % mod].size();j++) { if(h[x % mod][j].x == x) { k = h[x % mod][j].k;//取下标 h[x % mod][j].k = i;//更改下标为当前循环i break; } } return k; }
代码:
#include <bits/stdc++.h> using namespace std; struct node { int x,k; }; const int mod = 100007; int n,x,k,dp[1000007],ans; vector <node> h[1000007]; void insert(int x,int i) { h[x % mod].push_back((node){x,i}); } int find(int x,int i) { int k = 0; for(int j = 0;j < h[x % mod].size();j++) { if(h[x % mod][j].x == x) { k = h[x % mod][j].k; h[x % mod][j].k = i; break; } } return k; } int main() { cin >> n; for(int i = 1;i <= n;i++) { cin >> x; k = find(x,i); dp[i] = max(dp[i - 1],k + 1); ans = max(ans,i - dp[i] + 1); insert(x,i); } cout << ans; return 0; }
-
- 1
信息
- ID
- 385
- 时间
- 1000ms
- 内存
- 512MiB
- 难度
- 10
- 标签
- 递交数
- 10
- 已通过
- 2
- 上传者