|
马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
本帖最后由 柿子饼同学 于 2024-6-30 17:16 编辑
AcWing.272
提交 5 次
用时 2 h
知识点
线性dp
思路
设 f(i, j) 是 A前 i 个, B前 j 个数, 且以 Bj 结尾的 LCIS
Ai == Bj 时, ans = f(i - 1, k) + 1, 且满足 Bk < Bj = Ai, 0 < k < j
不等于时, ans = f(i - 1, j)
优化:
发现决策集合只增加, 每次 j 的循环中 i 是固定的, 即 Bk < Ai 的条件是固定下来的
所以遇到 Bj < Ai 时就用 temp = max(temp, f(i - 1, j)) 更新决策集合
另一种视角: 相等时只能从 Bk < Bj 转移过来
f 数组可以压成 1 维, f(j) 代表以 Bj 结尾的和 A 的 LCIS
Ai == Bj 时, f(j) = max(f(j), maxv + 1)
小于时, 因为没有被更新到, 所以 f(j) 相当于 i - 1 阶段的 f(j)
需要进步
优化的时候知道是只增, 但是没写出来, 没有钉死 Ai 是固定的才导致写不了
在看次层循环时, 考虑优化的时候不用关心阶段(只是利用那个 j 的循环而已), 只需要保证现在选择的状态没被更新即可
代码#include <bits/stdc++.h>
using namespace std;
const int N = 3005;
int n, A[N], B[N], f[N];
int ans, mx;
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cin >> n;
for(int i = 1; i <= n; i++) cin >> A[i];
for(int i = 1; i <= n; i++) cin >> B[i];
for(int i = 1; i <= n; i++){
int maxv = 0;
for(int j = 1; j <= n; j++){
if(A[i] == B[j]) f[j] = max(f[j], maxv + 1);
if(A[i] > B[j]) maxv = max(maxv, f[j]);
}
}
for(int i = 1; i <= n; i++) ans = max(ans, f[i]);
cout << ans;
return 0;
}
|
|