Description
There is a sequence X (i.e. x[1], x[2], ..., x[n]). We define increasing subsequence of Xas x[i1], x[i2],...,x[ik], which satisfies follow conditions:
1) x[i1] < x[i2],...,<x[ik];
2) 1<=i1 < i2,...,<ik<=n
As an excellent program designer, you must know how to find the maximum length of the
increasing sequense, which is defined as s. Now, the next question is how many increasing
subsequence with s-length can you find out from the sequence X.
For example, in one case, if s = 3, and you can find out 2 such subsequence A and B from X.
1) A = a1, a2, a3. B = b1, b2, b3.
2) Each ai or bj(i,j = 1,2,3) can only be chose once at most.
Now, the question is:
1) Find the maximum length of increasing subsequence of X(i.e. s).
2) Find the number of increasing subsequence with s-length under conditions described (i.e. num).
Input
The input file have many cases. Each case will give a integer number n.The next line willhave n numbers.
Output
The output have two line. The first line is s and second line is num.Sample Input
4
3 6 2 5
Sample Output
2
2
题意:给你一个序列,求此序列的最长上升子序列的值s以及值为s的最长上升子序列的个数;
思路:求出最长上升子序列的值s后将原数组中的这些数删除,然后再次求最长上升子序列,重复操作,一直到所求得的最长上升子序列的值不等于s。如何删除原数组的数,
只需要用一个标记数组记录一下哪些数已经用过了就可以了;#include<iostream>
#include<cstdlib>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<map>
#define INF 0x3f3f3f3f
#define N 1000
using namespace std;
int b[N],a[N],dp[N],n;
int maxlen()
{
int i,res,k=-1;
for(i=0; i<n; i++)
{
if(b[i])//如果当前数已经选取过了,跳过;
continue;
*lower_bound(dp,dp+n,a[i])=a[i];
int d=lower_bound(dp,dp+n,a[i])-dp;
if(d>k)//使用二分查找插入的位置应该满足大于k才可以进行标记,避免标记多余的数;另外由于d最小是0,所以k应当从-1开始;(单步调试一下很容易就能明白了)
{
b[i]=1;
k++;
}
}
res=lower_bound(dp,dp+n,INF)-dp;
return res;
}
int main()
{
int i,answer,ans;
while(~scanf("%d",&n))
{
memset(b,0,sizeof(b));
memset(a,0,sizeof(a));
for(i=0; i<n; i++)
scanf("%d",&a[i]);
int num=1;
fill(dp,dp+n,INF);
ans=maxlen();
while(1)
{
fill(dp,dp+n,INF);
answer=maxlen();
if(answer!=ans)
break;
else
num++;
}
printf("%d\n%d\n",ans,num);
}
return 0;
}