当前位置: 首页 > article >正文

【东方oj题解】1893、1821、1822

1893 - 最长上升子序列LIS(2)

题目描述

给定一个长度为 N 的数列,求数值严格单调递增的子序列的长度最长是多少。

输入

第一行包含整数 N 。

第二行包含 N 个整数,表示完整序列。

#include <bits/stdc++.h>
using namespace std;
//dp:长度为i的LIS的最后一位最小值是多少
int a[100100],dp[100100];
int i,n,l,r,mid;


int main() {
//读入
	scanf("%d",&n);
	for(i =1; i<= n; i++) {
		scanf("%d",&a[i]);
	}
//边界
	dp[1]= a[1];
	int len=1;
//LIs的长度//从第2个数开始求解
	for(i =2; i <= n; i++) { //如果 a[i]比 dp 最后一位大,a[i]直接续上去,增加 LIS的长度
		if(a[i]> dp[len]) {
			len++;
			dp[len]= a[i];
		} else {
//二分查找到 dp数组中第1个>=a[i]的元素下标,替换(dp 数组一定是递增的)
			l = 1;
			r= len;
			while(l <= r) {
				mid=(l+r)/2;
				if(a[i]<= dp[mid])r=mid -1;
				else l=mid +1;
			}
//替换
			dp[l]= a[i];
		}
	}
	printf("%d",len);

	return 0;
}


1821 - 最长公共子序列(LCS)(1)

#include <bits/stdc++.h>
using namespace std;
/*
a[i]==b[j],方程:dp[i-1][j-1]+1
a[i]!=b[j],方程:max(dp[i][j-1],dp[i-1][j])*/
const int N=1010;//常量,表示数组大小
int a[N],b[N],dp[N][N];
int n,i,j;
int main() {
	cin>>n;
	for(i =1; i<= n; i++)cin>>a[i];
	for(i =1; i<= n; i++)cin>>b[i];
//递推
	for(i = 1; i<= n; i++) {
		for(j = 1; j<= n; j++) {
			if(a[i]== b[j])dp[i][j]= dp[i-1][j-1]+ 1;
			else dp[i][j]= max(dp[i-1][j],dp[i][j-1]);
		}
	}
	cout<<dp[n][n];



	return 0;
}

1822 - 最长公共子序列(LCS)(2)

#include <bits/stdc++.h>
using namespace std;
/*原理:
1、因为两个序列都是1~n的全排列,那么两个序列元素互异且相同,也就是说只是位置不同;
2、通过c数组将b序列的数字在a序列中的位置求出;
3、如果b序列每个元素在a序列中的位置递增,说明b中的这个数在a中的这个数整体位置偏后,可以考虑纳入LCS;
4、从而就可以转变成求用来记录新的位置的c数组中的LIS。*/
const int N=100100;
int a[N],b[N],c[N],dp[N];
int n,i;

int main() {

	cin>>n;
	for(i=1; i<= n; i++) {
		scanf("%d",&a[i]);
		c[a[i]]=i;//求出a数组的每个数的位置
	}
	for(i =1; i<= n; i++)scanf("%d",&b[i]);
//求b数组的每个数在a数组的位置(c[b[i]])的 LIS
	dp[1]=c[b[1]];//边界
	int len = 1;
	int l,r,mid;//从第2个数开始讨论
	for(i =2; i<= n; i++) { //增加 LIS 的长度
		if(c[b[i]] > dp[len]) {
			len++;
			dp[len]= c[b[i]];
		} else {
			l = 1;
			r= len;
			while(l<= r) {
				mid=(l+r)/2;
				if(c[b[i]]<= dp[mid])r= mid - 1;
				else l=mid +1;
			}
			dp[l]= c[b[i]];
		}
	}
	cout<<len;
	return 0;
}



http://www.kler.cn/a/354404.html

相关文章:

  • openwrt 常见编译问题及编译提速
  • 【C++经典例题】求1+2+3+...+n,要求不能使用乘除法、for、while、if、else、switch、case等关键字及条件判断语句
  • 代码随想录 哈希 test 8
  • L1G5000 XTuner 微调个人小助手认知
  • 智慧公厕大数据驱动下的公共卫生管理与优化
  • 比较procfs 、 sysctl和Netlink
  • C++研发笔记2——学习规划概览
  • docker方式k8s环境搭建及pod简介
  • FFmpeg的简单使用【Windows】--- 视频混剪+添加背景音乐
  • 2. MySQL数据库基础
  • 医疗病历交互系统:Spring Boot技术解析
  • 【pytorch深度学习】CIFAR10图像分类
  • 【Mac苹果电脑安装】DBeaverEE for Mac 数据库管理工具软件教程【保姆级教程】
  • 【Linux安全基线】- CentOS 7/8安全配置指南
  • C++设计模式 单例模式
  • 滚雪球学Redis[6.2讲]:Redis脚本与Lua:深入掌握Redis中的高效编程技巧
  • ModuleNotFoundError: No module named ‘pdfminer.high_level‘
  • buffer/cache内存优化_posix_fadvise_主动释放读缓存cache
  • 安卓开发中轮播图和其指示器的设置
  • 云原生后端高阶用法
  • PHP爬虫:从入门到精通实战指南
  • PHP DateTime基础用法
  • 使用 Elasticsearch Dump 工具进行生产环境到测试环境的数据迁移与备份
  • Android blueprint/microfactory/microfactory.bash源码分析
  • C++ -string -常见用法2
  • No.17 笔记 | XXE漏洞:XML外部实体注入攻击