您的位置:首页 > 其它

hdu 5087 Revenge of LIS II ( LIS ,第二长子序列)

2017-05-07 16:56 309 查看
链接: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" style="color:rgb(204,204,204); text-decoration:none; background-color:inherit; border:none; padding:0px; margin:0px 10px 0px 0px; font-size:9px">?

#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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: