CF10D LCIS-Solution

感觉有点像最长公共子串,

但是那个是绿题,这个是蓝题,那肯定不一样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;
}
posted @ 2022-06-04 22:17  zcxxxxx  阅读(17)  评论(0编辑  收藏  举报