hdu 5087 Revenge of LIS II ( LIS ,第二长子序列)
2017-05-07 16:56
309 查看
链接:hdu 5087
题意:求第二大的最长升序子序列
分析:这里的第二大指的是,全部的递增子序列的长度(包含相等的),
从大到小排序后。排在第二的长度
思路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;
}
题意:求第二大的最长升序子序列
分析:这里的第二大指的是,全部的递增子序列的长度(包含相等的),
从大到小排序后。排在第二的长度
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;
}
相关文章推荐
- hdu 5087 Revenge of LIS II ( LIS ,第二长子序列)
- hdoj 5087 Revenge of LIS II 【第二长单调递增子序列】
- hdu 5087 Revenge of LIS II
- hdu 5087 Revenge of LIS II(LIS,思路)
- HDU 5087 Revenge of LIS II(BestCoder Round #16)(次长上升子序列)
- HDU - 5087 Revenge of LIS II
- hdu5087——Revenge of LIS II
- HDU 5087 Revenge of LIS II(次大递增子序列)
- hdu 5087 Revenge of LIS II (DP)
- hdu 5087 Revenge of LIS II(LIS)
- 【DP】 HDU 5087 Revenge of LIS II
- HDU5087——Revenge of LIS II(BestCoder Round #16)
- 【DP】 HDU 5087 Revenge of LIS II
- HDOJ 题目5087 Revenge of LIS II(第二长LIS)
- HDU 5087 Revenge of LIS II(次长上升子序列)
- Revenge of LIS II(HDU 5087)
- hdu 5087 Revenge of LIS II
- hdu 5087 Revenge of LIS II(BestCoder Round #16)
- Revenge of LIS II (hdu 5087 LIS)
- hdoj 5087 Revenge of LIS II 【第二长单调递增子】