标签:hdu
3 2 1 1 4 1 2 3 4 5 1 1 2 2 2
1 3 2HintFor the first sequence, there are two increasing subsequence: [1], [1]. So the length of the second longest increasing subsequence is also 1, same with the length of LIS.
题目大意:求一个序列的所有递增子序列中第二长的那个递增子序列的长度。
解题思路:根据dp求解一个序列的最大递增子序列的模板,dp[i]表示以第i个数结尾的最长上升子序列的长度 ,c[i]表示到达dp[i]的方法数,比如序列1 2 2 3 2;dp[2]=2,c[2]=1;dp[3]=2,c[3]=1;dp[4]=3,c[4]=2。
最后查询最大递增子序列出现的次数,如果出现一次,就最大长度减一输出;如果出现不止一次,就输出最大长度。
代码如下:
#include <cstdio> #include <cstdlib> #include <cstring> #include <cmath> #include <ctime> #include <iostream> #include <algorithm> #include <string> #include <vector> #include <deque> #include <list> #include <set> #include <map> #include <stack> #include <queue> #include <numeric> #include <iomanip> #include <bitset> #include <sstream> #include <fstream> #include <limits.h> #define debug "output for debug\n" #define pi (acos(-1.0)) #define eps (1e-6) #define inf (1<<28) #define sqr(x) (x) * (x) #define mod 1000000007 using namespace std; typedef long long ll; typedef unsigned long long ULL; const int MAX=1005; int a[MAX],c[MAX],dp[MAX]; int main() { int i,j,n,t; scanf("%d",&t); while(t--) { scanf("%d",&n); int ans=0; for(i=1;i<=n;i++) { scanf("%d",&a[i]); dp[i]=1,c[i]=1; for(j=1;j<i;j++) { if(a[i]>a[j]&&dp[i]<dp[j]+1) { dp[i]=dp[j]+1; c[i]=c[j]; } else if(dp[i]==dp[j]+1) c[i]=2; } ans=max(ans,dp[i]); } int num=0; for(i=1;i<=n;i++) { if(dp[i]==ans) num+=c[i]; } if(num==1) printf("%d\n",ans-1); else printf("%d\n",ans); } return 0; }
版权声明:本文为博主原创文章,未经博主允许不得转载。
HDU 5087 Revenge of LIS II(次大递增子序列)
标签:hdu
原文地址:http://blog.csdn.net/yanghuaqings/article/details/47726259