HDU 5748 Bellovin

来源:互联网 发布:农村人的劣根性知乎 编辑:程序博客网 时间:2024/05/21 10:19

题意:
这里写图片描述

个人感想:其实很容易就能想到,每个一ai结尾的最长上升子序列的长度的值就正是要输出的答案,可是最长上升子序列又怎么求呢..如果每个都求一次,那肯定是n^2 ,必然超时,那么我们得怎么做呢? 因为长度不超过10W,那么就办,那么我们就要有一个倒过来的思想,枚举长度! 通过更新长度的最小值,我就们可以快速的求出答案了
len(x):代表长度x.
L(x ):代表长度为x的最小value;
例如 2 1 3 4 5
第一个 2 的长度必然会是 len(1),L(1)=2;
第二个 1 就查看L(1)长度的值比不比他大, 明显 2>1;所以在这长度上更新 1的最长长度,所以 长度为len(1),可是同样长度都为len(1), 1比2小,那么我就更新L(1)的值是1;
第三个 3 就查看前面最长的长度,因为没出现过最长长度为len(2)所以肯定不能从L(2)开始,只能从L(1),明显 3>1大,那么3的最长长度就是len(2)了,同时更新L(2)的值为3了..
第4,5 同3.就可以快速的找到所有的最长子序列了..复杂度也可能是n^2 当我自己出的数据就没试过有n^2的 一般都在 nlogn范围内求出答案了.

分析:变形最长上升子序列

代码:

/* Author:GavinjouElephant * Title: * Number: * main meanning: * * * *///#define OUT#include <iostream>using namespace std;#include <cstdio>#include <cmath>#include <cstring>#include <algorithm>#include <sstream>#include <cctype>#include <vector>#include <set>#include <cstdlib>#include <map>#include <queue>//#include<initializer_list>//#include <windows.h>//#include <fstream>//#include <conio.h>#define MaxN 0x7fffffff#define MinN -0x7fffffff#define Clear(x) memset(x,0,sizeof(x))const int INF=0x3f3f3f3f;const int maxn=1e5+10;int N;int a[maxn];int dp[maxn];int T;int top;int value[maxn];int main(){#ifdef OUT    freopen("coco.txt","r",stdin);    freopen("lala.txt","w",stdout);#endif     scanf("%d",&T);     while(T--)     {         top=1;         dp[0]=0;         memset(dp,0,sizeof(dp));         memset(value,0x3f,sizeof(value));         value[0]=0;         scanf("%d",&N);         for(int i=0;i<N;i++)         {             scanf("%d",&a[i]);         }         /*for(int i=0;i<N;i++)         {             cout<<a[i]<<" ";         }         cout<<endl;*/         for(int i=0;i<N;i++)         {             for(int j=top-1;j>=0;j--)             {                 if(value[j]<a[i])                 {                     dp[i]=j+1;                     value[j+1]=min(value[j+1],a[i]);                     if((j+1)>=top)                     {                         top=j+2;                     }                     //cout<<top<<endl;                     break;                 }             }         }         for(int i=0;i<N;i++)         {             if(i==0)printf("%d",dp[i]);             else printf(" %d",dp[i]);         }         printf("\n");     }    return 0;}
0 0
原创粉丝点击