题目传送门:https://www.luogu.com.cn/problem/P1020
100分写法:
时间复杂度O(N*N)
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<sstream>
#include<stack>
#include<map>
#include<set>
using namespace std;
const int MAXN = 100005;
const int INF = 0x7fffffff;
int a[MAXN];
int dp[MAXN]; //dp[i]表示长度为i的子序列结尾数字的最小值。
//dp[i]表示以a[i]结尾,最长不上升子序列的长度。
int read(){
string str;
int i,u,v,len;
u = 0;
i = 0;
getline(cin,str);
while(true){
if(str.find(" ",u) == string::npos){
istringstream input(str.substr(u));
input>>a[++i];
break;
}
v = str.find(" ",u);
len = v - u;
istringstream input(str.substr(u,len));
u = v + 1;
input>>a[++i];
}
return i;
}
//最常不上升子序列
int LDS(int n){
int ans = 0;
for(int i=1;i<=n;i++){
dp[i] = 1;
for(int j=1;j<i;j++){
if(a[i] <= a[j]){
dp[i] = max(dp[j]+1,dp[i]);
}
}
ans = max(ans,dp[i]);
}
return ans;
}
//最长上升子序列
int LIS(int n){
int ans = 0;
for(int i=1;i<=n;i++){
dp[i] = 1;
for(int j=1;j<i;j++){
if(a[i] > a[j]){
dp[i] = max(dp[j]+1,dp[i]);
}
}
ans = max(ans,dp[i]);
}
return ans;
}
int main(){
int n = read();
cout<<LDS(n)<<endl;
cout<<LIS(n)<<endl;
return 0;
}
200分写法
时间复杂度:nlogn
#include<iostream>
#include<algorithm>
#include<vector>
#include<string>
#include<sstream>
#include<stack>
#include<map>
#include<set>
using namespace std;
const int MAXN = 100005;
const int INF = 0x7fffffff;
int a[MAXN];
int dp[MAXN]; //dp[i]表示长度为i的子序列结尾数字的最小值。
int read(){
string str;
int i,u,v,len;
u = 0;
i = 0;
getline(cin,str);
while(true){
if(str.find(" ",u) == string::npos){
istringstream input(str.substr(u));
input>>a[++i];
break;
}
v = str.find(" ",u);
len = v - u;
istringstream input(str.substr(u,len));
u = v + 1;
input>>a[++i];
}
return i;
}
bool cmp(const int &a,const int &b){
return a>b;
}
//最常不上升子序列
int LDS(int n){
dp[1] = a[1];
int index = 1;
for(int i=2;i<=n;i++){
if(a[i] <= dp[index]){
dp[++index] = a[i];
}else{
int *k = upper_bound(dp+1,dp+index,a[i],cmp);
*k = a[i];
}
}
return index;
}
//最长上升子序列
int LIS(int n){
dp[1] = a[1];
int index = 1;
for(int i=2;i<=n;i++){
if(a[i] > dp[index]){
dp[++index] = a[i];
}else{
int *k = lower_bound(dp+1,dp+index,a[i]);
*k = a[i];
}
}
return index;
}
int main(){
int n = read();
cout<<LDS(n)<<endl;
cout<<LIS(n)<<endl;
return 0;
}