最长上升子序列c++代码
时间: 2024-06-19 15:02:32 浏览: 117
最长上升子序列是指在一个无序的数列中,找到一个子序列,使得这个子序列中的元素在原数列中的位置是单调递增的,并且这个子序列的长度最长。以下是一份C++代码示例:
```
int lengthOfLIS(vector<int>& nums) {
if (nums.empty()) {
return 0;
}
int n = nums.size();
vector<int> dp(n, 1);
int ans = 1;
for (int i = 1; i < n; ++i) {
for (int j = 0; j < i; ++j) {
if (nums[i] > nums[j]) {
dp[i] = max(dp[i], dp[j] + 1);
}
}
ans = max(ans, dp[i]);
}
return ans;
}
```
相关问题
最长公共上升子序列C++代码
#include<bits/stdc++.h>
using namespace std;
const int maxn=1005;
int n,m,a[maxn],b[maxn],f[maxn][maxn],pre[maxn][maxn];
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
for(int i=1;i<=m;i++) scanf("%d",&b[i]);
for(int i=1;i<=n;i++){
int last=0;
for(int j=1;j<=m;j++){
f[i][j]=f[i-1][j];
pre[i][j]=pre[i-1][j];
if(a[i]==b[j]){
f[i][j]=f[last][j-1]+1;
pre[i][j]=last;
}
if(a[i]>b[j]&&f[i-1][j]>f[last][j-1]){
f[i][j]=f[i-1][j];
pre[i][j]=pre[i-1][j];
}
if(a[i]==b[j]) last=i;
}
}
int ans=0,pos=0;
for(int i=1;i<=n;i++){
if(f[i][m]>ans){
ans=f[i][m];
pos=i;
}
}
printf("%d\n",ans);
if(ans==0) return 0;
vector<int>res;
while(m){
res.push_back(a[pos]);
pos=pre[pos][m--];
}
for(int i=res.size()-1;i>=0;i--) printf("%d ",res[i]);
return 0;
}
最长上升子序列c++
### 回答1:
最长上升子序列(Longest Increasing Subsequence, LIS)是指一个序列中最长的严格递增子序列的长度。以下是 C++ 实现 LIS 的示例代码:
```c++
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
int main() {
vector<int> nums = {10, 9, 2, 5, 3, 7, 101, 18};
vector<int> dp(nums.size(), 1); // dp[i] 表示以 nums[i] 结尾的最长上升子序列长度
int res = 1; // 记录最大长度
for (int i = 1; i < nums.size(); i++) {
for (int j = 0; j < i; j++) {
if (nums[j] < nums[i]) {
dp[i] = max(dp[i], dp[j] + 1); // 状态转移方程
}
}
res = max(res, dp[i]);
}
cout << res << endl; // 输出最长上升子序列长度
return 0;
}
```
该代码的时间复杂度为 O(n^2),可以通过二分查找优化到 O(nlogn)。
### 回答2:
最长上升子序列(Longest Increasing Subsequence)是指在一个给定序列中,找出一个最长的子序列使得子序列中的元素按照顺序递增。给定一个长度为n的序列A,最长上升子序列的长度可以通过动态规划的方法求解。
假设dp[i]表示以第i个元素结尾的最长上升子序列的长度,那么状态转移方程可以定义为:
dp[i] = max(dp[j] + 1), 其中0 <= j < i,A[j] < A[i]
首先,初始化dp数组为1,表示每个元素本身就构成一个长度为1的最长上升子序列。
然后,从左往右遍历数组A,对于每个元素A[i],遍历之前的所有元素A[j](j<i),如果A[j] < A[i],则更新dp[i]为dp[j]+1。
最后,返回dp数组中的最大值即为最长上升子序列的长度。
举个例子,给定序列A=[3, 10, 2, 1, 20],首先初始化dp数组为[1, 1, 1, 1, 1]。
遍历到元素10时,与3比较,满足条件A[j] < A[i],更新dp[1]为dp[0]+1,得到dp=[1, 2, 1, 1, 1]。
再遍历到元素2时,与3和10比较,均不满足条件,不更新dp数组,得到dp=[1, 2, 1, 1, 1]。
继续遍历到元素1时,与3、10和2比较,满足条件A[j] < A[i],更新dp[3]为dp[2]+1,得到dp=[1, 2, 1, 2, 1]。
最后遍历到元素20时,与3、10、2和1比较,均满足条件,更新dp[4]为dp[3]+1,得到dp=[1, 2, 1, 2, 3]。
返回dp数组中的最大值3,即为最长上升子序列的长度。
综上所述,利用动态规划可以求解最长上升子序列的长度。
### 回答3:
最长上升子序列(Longest Increasing Subsequence,LIS)是指在一个给定序列中,找到一个最长的子序列,使得这个子序列中的元素按照严格递增的顺序排列。
设序列为a[1…n],定义dp[i]为以a[i]结尾的LIS的长度。那么转移方程可以表示为:dp[i] = max{dp[j] + 1 | 1 ≤ j < i, a[j] < a[i]}。
根据状态转移方程,我们需要遍历所有小于i的j,找到能够构成最长上升子序列的j,从而更新dp[i]。可以使用动态规划的思路,通过一个辅助数组dp来记录每个位置的最长上升子序列长度。
具体实现上,我们可以使用两个循环来遍历序列a,外层循环从1到n,内层循环从1到i。在内层循环中,比较a[j]和a[i]的大小,若满足条件则更新dp[i]为较大值。
最后,我们只需要遍历dp数组中的最大值,即为最长上升子序列的长度。
例如,对于序列c = [1, 3, 5, 2, 4, 6, 7],通过使用动态规划的方法,我们可以得到dp = [1, 2, 3, 2, 3, 4, 5]。最长上升子序列的长度为5。
最长上升子序列问题是一个经典的动态规划问题,它的时间复杂度为O(n^2)。同时,还存在更优化的解法,比如使用二分查找加速查找过程,将时间复杂度优化为O(nlogn)。
阅读全文