4 条题解
-
1
这道题好,之前野路子LIS2解法各种超时。逼着人家找到最优的解法。
#include <bits/stdc++.h> using namespace std; inline int read() { int x = 0, f = 1; char ch = getchar(); while (!isdigit(ch)) {if (ch == '-')f = -1; ch = getchar();} while (isdigit(ch)) {x = (x << 1) + (x << 3) + (ch ^ 48); ch = getchar();} return x * f; } int main() { int n = read(); int pa[n + 1]; for (int i = 0; i < n; i++) pa[read()] = i; int longest_head[n + 1]; register int a, longest = 1; longest_head[1] = pa[read()]; longest_head[0] = 0; pa[0] = 0; for (register int i = 1; i < n; i++) { a = pa[read()]; if (longest_head[longest] < a) longest_head[++longest] = a; auto x = upper_bound(longest_head, longest_head + longest, a); *x = a; } cout << longest; }
-
0
/* 对于两个长度一样的序列例如, 5 3 1 2 4 2 3 4 5 1找最长公共子序列 可以这样做,我们不妨建立一个映射关系。 5-1,3-2,1-3,2-4,4-5 那么第一个数列变成1 2 3 4 5 第二个数列就是4 2 5 1 3 这时,第一个数列就是单调递增 找两个数列的公共子序列,因为第一个数列递增 所以公共子序列在第二个也递增,因此就变成了找第二个数列的最长上升子序列问题。 有了这样的基础以后,就是利用年课的学习二分优化解决最长上升子序列问题。 设置一个d数组,初始化极大值。在d数组找到刚好大于当前数字b[i]的下标now 就可以进行拼接过去。然后修改d数组 */ #include<bits/stdc++.h> using namespace std; int n,a[100005],b[100005],f[100005],d[100005],ans; map<int,int> m;//建立映射关系 int main() { cin>>n; for(int i=1;i<=n;i++) { cin>>a[i]; m[a[i]]=i;//建立映射关系 } for(int i=1;i<=n;i++) { cin>>b[i]; b[i]=m[b[i]];//修改b数组 } memset(d,0x3f,sizeof(d)); for(int i=1;i<=n;i++) { int now=lower_bound(d+1,d+n+1,b[i])-d; f[i]=now; d[now]=b[i]; ans=max(ans,f[i]); } cout<<ans; }
-
-1
写题解请注意 鼓励大家写题解,但注意题解格式。
题解一定要有思路解析或代码注释,能否让别人理解你的思路
也是你的能力的检验,不要只放无意义的代码给大家复制,那就失去了做题的初心。
给代码两端加上这个会舒服一些
```cpp
你的代码
```
</span>
这个点在键盘的左上角tab上面那个键,注意切换输入法
#include<iostream> using namespace std; int main() { int n; cin>>n;//这是一个注释 return 0; }
请注意严禁抄袭题解,写题解不要只放代码,需加上你的思路或代码注释。
抄袭题解一经发现直接取消成绩。
题解被删除的可能
- 代码不符合格式规范
- 没有思路讲解或者没有注释,
- 无意义的题解
大家携手共同维护一个良好的编程环境,如果一经发现,多次作乱。可能会被管理员拉黑,请注意,一旦拉黑即失去登陆资格。
- 1
信息
- ID
- 818
- 时间
- 1000ms
- 内存
- 128MiB
- 难度
- 4
- 标签
- 递交数
- 39
- 已通过
- 18
- 上传者