Deleting Sequence(LIS)

来源:互联网 发布:电脑版淘宝客服打不开 编辑:程序博客网 时间:2024/06/06 02:41

题意:给一个数列,删除其中任意多个数后数列中的一些数的值等于其下标(从1开始计算),那么得到的数列最多能有多少个这样的数。

题目链接:http://acm.ustc.edu.cn/ustcoj/status.php?from=10&contest=46

解法:另原数列为a[],b[i]=i+2-a[i].将b[i]>0的排序,然后求a[]的最长递增序列即可(nlogn的复杂度)。

 代码:

#include <iostream>#include <stdio.h>#include <algorithm>#include <cstring>#define inf 2000000000#define MAX 500100using namespace std;struct point{    int x,y;};bool operator<(point a,point b){    if(a.y<b.y) return true;    if(a.y>b.y) return false;     return a.x<b.x;}int tool[MAX];point num[MAX];int up[MAX];//up[j]表示从num[0]到num[j],以num[j]结尾的最长升序长度int down[MAX];int D[MAX];//辅助数组int n;int N;int ans=0;int make(int up[])//up[j]表示从num[0]到num[j],以num[j]结尾的最长升序长度{    if(N==0) return 0;    D[0]=-inf;    memset(up,0,sizeof up);    up[0]=1;    D[1]=num[0].x;    int ma=1;    for(int i=1;i<N;i++)    {        up[i]=lower_bound(D,D+ma+1,num[i].x)-D;//lower_bound计算的是严格升序         //up[i]=upper_bound(D,D+ma+1,num[i])-D;//upper_bound计算的是非严格升序(可以相等)        if(up[i]>ma)        {            ma=up[i];            D[ma]=num[i].x;        }        D[up[i]]=min(num[i].x,D[up[i]]);    }    return ma;}int main(){    int t;    cin>>t;    while(t--)    {        scanf("%d",&n);N=0;        for(int i=0;i<n;i++)        {            scanf("%d",&tool[i]);//存储数据            if(i+2-tool[i]>0)            {            num[N].x=tool[i];            num[N++].y=i+2-tool[i];            }        }        sort(num,num+N);         cout<<make(up)<<endl;    }}/*3101 1 2 5 4 5 7 6 8 76*/

0 0
原创粉丝点击