文章

68

粉丝

691

获赞

26

访问

578.3k

头像
利用题意的数据不重复的条件
P1629 上海交通大学2019年机试题
发布于2020年5月31日 15:46
阅读数 11.7k

虽然我感觉代码可能有点问题,但是依然是过了,大佬看出错误的话麻烦告诉我,n^2也能水过,想了一下每个序列中的元素都不重复,那么也就是说a2中的每个元素,最多有一个a1中的元素与之相等,在我们O(n^2)的算法中,我们的更新公式是

	for (int i = 1; i <= n; i++) {
		for (int j = 1; j <= n; j++) {
			if (a1[i] == a2[j])dp[i][j] = dp[i - 1][j - 1] + 1;
			else dp[i][j] = max(dp[i - 1][j], dp[i][j - 1]);
		}
	}

怎样才能利用已知条件把算法改成O(n)的,100w的数据nlogn也会T掉吧,其实在第二个for循环中,我们只会遇到一次a1[i]==a2[j](数据不重复),因此我们用unorderedmap存储a1中的元素出现的位置,将第二个for循环去掉,如果a2[i]在map中出现过,显然有一个相等元素,那么如果他出现的位置比a2[i-1]在 a1中出现的位置还晚(如果出现的早的话是不可以的,比如1 3 2和1 2 3,a2中的3出现在a1中的位置比2早,1 2 3不是一个公共子序列),那么最长公共字串就可以+1,否则继承到上个元素为止的最大值,类似于dp[i][j]=max(dp[i-1][j],dp[i][j-1])操作。

#define ll long long
#define inf 0x3f3f3f3f
#define MAX 1000005
#define vec vector<int>
#define P pair<int,int>

int main() {
	int n, a1[MAX], a2[MAX], t[MAX];
	while (cin >> n) {
		unordered_map<int, int> m; m[0] = 0;
		for (int i = 1; i <= n; i++)cin >> a1[i], m[a1[i]] = i;//O(n)
		//由于元素均不相同,因此和a2[i]相同的a1中的元素不超过...
登录查看完整内容


登录后发布评论

2 条评论
sdssdadsa
2021年3月19日 21:06

测试样例:

4
4 5 1 2
1 2 4 5

你的代码输出:3

正确答案:2

第二个数组遍历到4出现失配直接继承了已匹配长度2,遍历到5时因为第一个数组中5在4后面就直接在继承来的长度后面加1,显然思路是不对的。但是这题样例也太水了,n^2都能过

赞(0)

admin : 回复 sdssdadsa: 这个代码过不了哈,中途数据加强过

2021年3月20日 22:11