首页 > 代码库 > hdu 5087 Revenge of LIS II ( LIS ,第二长子序列)
hdu 5087 Revenge of LIS II ( LIS ,第二长子序列)
链接:hdu 5087
题意:求第二大的最长升序子序列
分析:这里的第二大指的是,所有的递增子序列的长度(包括相等的),
从大到小排序后,排在第二的长度
BestCoder Round #16 上的第二题,注意 1 1 2 这组数据,答案应为2
思路1.每次将最长的两个上升子序列长度记录,最后再排序,取第二大的即可
思路2.如果最长的上升子序列长度(ans)唯一,那第二大应为ans-1
否则,第二大的就为 ans
[cpp] view plaincopyprint?
- #include<stdio.h>
- #include<algorithm>
- using namespace std;
- int a[1010],dp[1010][2],ans[2010],n;
- int main()
- {
- int T,i,j,k,x,y;
- scanf("%d",&T);
- while(T--){
- scanf("%d",&n);
- for(i=0;i<n;i++)
- scanf("%d",&a[i]);
- k=0;
- for(i=0;i<n;i++){
- dp[i][0]=1;
- dp[i][1]=0;
- for(j=0;j<i;j++){
- if(a[j]<a[i]){
- x=dp[j][0]+1;
- y=dp[j][1]+1;
- if(x>dp[i][0]) //更新最大的两个长度
- swap(x,dp[i][0]);
- if(x>y)
- swap(x,y);
- if(y>dp[i][1])
- dp[i][1]=y;
- }
- }
- ans[k++]=dp[i][0]; //将每次最大的两个值记录下来
- ans[k++]=dp[i][1];
- }
- sort(ans,ans+k);
- printf("%d\n",ans[k-2]); //输出排序后第二大的
- }
- return 0;
- }
[cpp] view plaincopyprint?
- #include<stdio.h>
- #include<string.h>
- #define max(a,b) a>b?a:b
- int a[1010],dp[1010],num[1010],n;
- int main()
- {
- int T,i,j,cnt,ans;
- scanf("%d",&T);
- while(T--){
- scanf("%d",&n);
- for(i=0;i<n;i++)
- scanf("%d",&a[i]);
- ans=1;
- for(i=0;i<n;i++){
- num[i]=dp[i]=1;
- for(j=0;j<i;j++){
- if(a[j]<a[i]&&dp[j]+1>dp[i]){
- dp[i]=dp[j]+1;
- num[i]=num[j]; //记录出现的次数
- }
- else if(a[j]<a[i]&&dp[j]+1==dp[i])
- num[i]+=num[j]; //记录出现的次数
- }
- ans=max(ans,dp[i]); //记录最大值
- }
- cnt=0;
- for(i=0;i<n;i++)
- if(dp[i]==ans)
- cnt+=num[i]; //计算最大值出现的总次数
- if(cnt==1) //这里改成cnt>1输出ans,否则ans-1,wrong了,很郁闷
- printf("%d\n",ans-1);
- else
- printf("%d\n",ans);
- }
- return 0;
- }
hdu 5087 Revenge of LIS II ( LIS ,第二长子序列)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。