hdu6635 Nonsense Time(暴力+LIS)

阅读: 评论:0

hdu6635  Nonsense Time(暴力+LIS)

hdu6635 Nonsense Time(暴力+LIS)

题意:

给出n个数字,全部被冻结,每次解冻其中一个数字,共解冻n次,求解每轮解冻之后,解冻数组中的最长上升子序列。

 

思路:

反向思考,先计算出最后一次的最长上升子序列,并将序列储存到set中,然后每次减少一个数,判断这个数是否在set中,若不在则表示去除的数不会影响最长上升子序列长度,否则重新暴力求解新序列的最长上升子序列。

(PS:看题解说时间复杂度为O(nn log n),但并不知道为什么,还是太菜啊)

AC代码:

#include <bits/stdc++.h>using namespace std;const int maxn = 5e4 + 10;
#define cls(x) memset(x,0,sizeof(x))int a[maxn];
int s[maxn];
int dp[maxn];
int f[maxn];
int ans[maxn];int main()
{int t,n;scanf("%d",&t);while(t--){scanf("%d",&n);for(int i = 1; i <= n; i++){scanf("%d",&a[i]);}for(int i = 1; i <= n; i++){scanf("%d",&s[i]);}int nn = n ;int k;set<int> ss;while(nn != 1){if(nn!=n){a[s[nn+1]] = -1;}if(nn == n || ss.find(s[nn+1])!&#d()){cls(dp);ss.clear();int kk=2;for(int i = 1; i <= n; i++){if(a[i]!= -1){dp[1] =  a[i];f[i] = 1;kk = i+1;break;}}k = 1;for(int i = kk; i <= n; i++){if(a[i]==-1)continue;if(a[i]>dp[k]){dp[++k] = a[i];f[i] = k;}else{int m = upper_bound(dp + 1,dp + k + 1,a[i])-dp;dp[m] = a[i];f[i] = m;}}ans[nn] = k;int maxx = 999999;int k1 = k;for(int i = n; i > 0; i--){if(k1<=0)break;if(f[i] == k1 && maxx > a[i]&&a[i]!=-1){ss.insert(i);k1--;maxx = a[i];}}}elseans[nn] = k;nn--;}ans[1] = 1;for(int i=1;i<=n;i++){if(i!=n)cout<<ans[i]<<" ";elsecout<<ans[i]<<endl;}}return 0;
}

 

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

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

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

标签:暴力   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