AcWing 1017. 怪盗基德的滑翔翼
原题链接
简单
作者:
烧仙草
,
2021-03-11 10:47:44
,
所有人可见
,
阅读 306
本题采取y总在最长单调序列时所作的2种方法。
分析本题得出本题分两个方向求最长单调递减序列,下面给出AC代码。
1
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=110;
int q[N],p[N];
int f[N];
int k,n;
int get_max(int n,int q[]){
int res=0;
for(int i=0;i<=n;i++) f[i]=1;
for(int i=1;i<=n;i++){
for(int j=1;j<=i;j++){
if(q[j]>q[i]) f[i]=max(f[i],f[j]+1);
}
}
for(int i=1;i<=n;i++) res=max(res,f[i]);
return res;
}
int main(){
scanf("%d",&k);
while(k--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
cin>>q[i];
p[n-i+1]=q[i];//读入不同方向数据在p、q数组中
}
int t=get_max(n,q);
t=max(t,get_max(n,p));
printf("%d\n",t);
}
return 0;
}
2
维护一个动态数组,利用贪心的思想每次二分查找大于它的最后一个数。
#include<iostream>
#include<algorithm>
#include<cstring>
using namespace std;
const int N=110;
int q[N],p[N];
int f[N];
int k,n;
int get_max(int n,int q[]){
int len=0;
for(int i=1;i<=n;i++){
int l=0;
int r=len;
while(l<r){
int mid=l+r+1>>1;
if(f[mid]>=q[i]) l=mid;
else r=mid-1;
}
f[r+1]=q[i];
if(r+1>len) len++;
}
return len;
}
int main(){
scanf("%d",&k);
while(k--){
scanf("%d",&n);
for(int i=1;i<=n;i++){
cin>>q[i];
p[n-i+1]=q[i];//读入不同方向数据在p、q数组中
}
int t=get_max(n,q);
t=max(t,get_max(n,p));
printf("%d\n",t);
}
return 0;
}