HDU 6635 Nonsense Time (多次求LIS)

阅读: 评论:0

HDU 6635 Nonsense Time (多次求LIS)

HDU 6635 Nonsense Time (多次求LIS)

题目链接

思路:

铁着头想就是遍历着求LIS,超时无疑,正难则反,先求出所有的元素都未被冻结时的LIS,然后一个一个冻结,检查冻结的点是否是LIS的关键点(即是否为LIS中的元素),如果不是,当前答案就是LIS长度,否则就需要重新跑一次LIS。

具体细节见代码注释。

另推荐另一大佬的解法,方法类似但可参考写法点这里看大佬代码

代码

#include<iostream>
#include<algorithm>
#include<cstdio>
using namespace std;
const int inf=0x3f3f3f3f;
const int maxn=5e4+7;
int dp[maxn];   ///LIS元素数组
int a[maxn];    ///原数组
int pos[maxn];  ///冻结数组
int n;
int book[maxn];  ///判断当前位置是否是关键点
int tot[maxn];   ///LIS长度数组
int ans[maxn];   ///存答案
void LIS(){fill(dp,dp+n,inf);fill(tot,tot+n,-1);fill(book,book+n,0);int maxl=0;for(int i=0;i<n;i++){if(a[i]!=inf){    ///该数字未被冻结int pos=lower_bound(dp,dp+n,a[i])-dp;  ///查找该数字在原LIS中的位置if(dp[pos]==inf){    ///如果这个位置比原LIS的长度大,更新LIStot[i]=pos;      ///记录下标dp[pos]=a[i];    ///储存该数字maxl=max(maxl,pos);   ///更新LIS长度}else{tot[i]=pos;dp[pos]=a[i];}}}for(int i=n-1;i>=0;i--){  ///从下标数组中找当前LIS的元素位置if(maxl<0)break;if(tot[i]==maxl){book[i]=1;    ///标记最长子序列的位置maxl--;}}
}int main(){int t;cin>>t;while(t--){cin>>n;for(int i=0;i<n;i++)cin>>a[i];LIS();  ///先求一次原始数组的LISfor(int i=0;i<n;i++){cin>>pos[i];pos[i]--;    ///为了让下标从零开始}for(int i=n-1;i>=0;i--){ans[i]=lower_bound(dp,dp+n,inf)-dp; ///找出当前LIS的长度if(book[pos[i]]==1){ ///如果该位置是原LIS的关键点,重新找LISa[pos[i]]=inf;   ///冻结该数字LIS();           ///重新查找}else{a[pos[i]]=inf;   ///冻结该数字}}for(int i=0;i<n;i++){cout<<ans[i];i==n-1?cout<<endl:cout<<" ";}}return 0;
}

本文发布于:2024-01-31 16:18:24,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170668910629805.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:HDU   Nonsense   LIS   Time
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23