CF10D LCIS-Solution
Link
感觉有点像最长公共子串,
但是那个是绿题,这个是蓝题,那肯定不一样qwq
整理一下思路:
设置状态:
设 \(f[i][j]\) 表示a串到i位置,b串到j位置,最长的公共子串长度。
枚举边界,因为这个状态的转移是从前边转移过来的,所以我们正向枚举。
转移,两种情况:
- 如果a[i] != b[j],f[i][j]直接继承f[i][j - 1]。
- 再就是相等的情况,接下来主要讨论这种情况。
当前枚举到(i, j)
最开始只包含这一位的时候 f[i][j]是等于1的。
所以初始化f[i][j] = 1
这时候在开一个新数组,表示到这一位最长lcis的长度。
初始化也为tot[j] = 1
枚举lcis的倒数第二位,从倒数第二位转移到当前这一位,同时对f[i][j]和tot[j]进行更新,还要记录一下当前形势下的最长lcis
code:
BOOM!!
/**
* author: zcxxxxx
* creater: 2022.6.3
**/
#include <bits/stdc++.h>
#define il inline
#define reg register
#define ll long long
#define pii pair<int, int>
using namespace std;
const int A = 5e2 + 7;
const int B = 1e3 + 7;
const int C = 1e4 + 7;
const int D = 1e5 + 7;
const int E = 1e6 + 7;
const int F = 1e7 + 7;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + 7;
ll Gcd(ll num1, ll num2) {return !num2 ? num1 : Gcd(num2, num1 % num2);}
ll tx, ty, tz; void Exgcd(ll num1, ll num2) {if(num2 == 0) {tx = 1, ty = 0; return;}
Exgcd(num2, num1 % num2), tz = tx, tx = ty, ty = tz - num1 / num2 * ty;}
/*General solution: tx += num2 / gcd * k, ty += num1 / gcd * k, k belong to Z*/
ll Gmul(ll x, ll y) {ll ans = 0; while(y != 0) {if(y & 1) ans = (ans + x) % mod; x = (x + x) % mod, y >>= 1;} return ans;}
ll Gpow(ll base, ll pow) {ll ans = 1;while(pow) {if(pow & 1) ans = Gmul(ans, base); base = Gmul(base, base);pow >>= 1;} return ans;}
ll Qpow(ll base, ll pow) {ll ans = 1;while(pow) {if(pow & 1) ans = (ans * base) % mod; base = (base * base) % mod;pow >>= 1;} return ans;}
inline int read() {register int x = 0, t = 1; register char ch = getchar();
while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar(); if(ch == '-') {t = -1; ch = getchar();}
while (ch >= '0' && ch <= '9') {x = x * 10 + ch - 48; ch = getchar();}return x * t;}
bool cmpbts(ll a, ll b) {return a > b;}
bool cmpstb(ll a, ll b) {return a < b;}
/*----------------------------------------*/
int a[A], b[A], n, m, f[A][A], lics[A][A], tot[A];
int main()
{
n = read();
for(int i = 1; i <= n; ++ i) a[i] = read();
m = read();
for(int i = 1; i <= m; ++ i) b[i] = read();
for(int i = 1; i <= n; ++ i) {
for(int j = 1; j <= m; ++ j) {
if(a[i] != b[j]) f[i][j] = f[i - 1][j];
else {
f[i][j] = 1, tot[j] = 1;
for(int k = 1; k < j; ++ k) {
if(b[k] < b[j]) {
if(f[i - 1][k] + 1 > f[i][j]) {
f[i][j] = f[i - 1][k] + 1;
tot[j] = tot[k] + 1;
for(int p = 1; p <= tot[k]; ++ p) {
lics[j][p] = lics[k][p];
}
}
}
}
lics[j][tot[j]] = b[j];
}
}
}
int ans = 0, pos = 0;
for(int i = 1; i <= m; ++ i) {
if(f[n][i] > ans) {
ans = f[n][i];
pos = i;
}
}
printf("%d\n", ans);
for(int i = 1; i <= tot[pos]; ++ i) {
printf("%d ", lics[pos][i]);
}
return 0;
}