求助贴,找的样例和自己试的数据都能过
  • 板块CF10D LCIS
  • 楼主Gavinprprpr
  • 当前回复1
  • 已保存回复1
  • 发布时间2023/1/11 15:53
  • 上次更新2023/10/24 04:44:24
查看原帖
求助贴,找的样例和自己试的数据都能过
818035
Gavinprprpr楼主2023/1/11 15:53

代码如下

#include<bits/stdc++.h>
using namespace std;
#define int long long
int arr1[600], arr2[600], dp[520][520],fnd[520][520],back[520][520], n, m, ans,jj;
//fnd[i][j]用来找(arr1从1到i)和(arr2从1到j)的LCIS的最后一位数字;
//back[i][j]用来回溯(arr1从1到i)和(arr2从1到j)的LCIS的倒数第二位数字的下标;
stack<int> s;
signed main()
{
	//输入
	cin >> n; for (int i = 1; i <= n; i++) { cin >> arr1[i]; }
	cin >> m; for (int i = 1; i <= m; i++) { cin >> arr2[i]; }arr2[0] = -1;
	//dp
	for (int i = 1; i <= n; i++) {//dp[i][j]为(arr1下标从1到i的数中)(以arr2[j]结尾的)(arr1和arr2的)最长公共上升子序列
		for (int j = 1; j <= m; j++) {
			if (arr1[i] == arr2[j]) {
				fnd[i][j] = arr2[j];
				for (int k = 0; k < j; k++) 
					if (arr2[j] > arr2[k]) {
						back[i][j] = ((dp[i - 1][k] + 1) > dp[i][j] ? k : back[i][j]);
						dp[i][j] = max(dp[i - 1][k] + 1, dp[i][j]);
					}
			}
			else { 
				dp[i][j] = dp[i - 1][j]; 
				fnd[i][j] = fnd[i - 1][j];
				back[i][j] = back[i - 1][j];
			}
			if (i == n) { //找到最大的dp及其下标
				ans = max(ans, dp[i][j]); 
				if (ans == dp[i][j]) { jj = j; }
			}
		}
	}
	//输出
	cout << ans<<endl;
	//回溯出来的是逆序的,用栈输出
	while (dp[n][jj]) {
		s.push(fnd[n][jj]);
		jj = back[n][jj];
		n--;
	}
	while (!s.empty()) {
		cout << s.top() << " ";
		s.pop();
	}
	return 0;
}
2023/1/11 15:53
加载中...