题目链接:
Time Limit: 2000/1000 MS (Java/Others)
Memory Limit: 65536/65536 K (Java/Others)
Problem Description
?? gets an sequence S with n intergers(0 < n <= 100000,0<= S[i] <= 1000000).?? has a magic so that he can change 0 to any interger(He does not need to change all 0 to the same interger).?? wants you to help him to find out the length of the longest increasing (strictly) subsequence he can get.
Input
The first line contains an interger T,denoting the number of the test cases.(T <= 10) For each case,the first line contains an interger n,which is the length of the array s. The next line contains n intergers separated by a single space, denote each number in S.
Output
For each test case, output one line containing “Case #x: y”(without quotes), where x is the test case number(starting from 1) and y is the length of the longest increasing subsequence he can get.
Sample Input
2
7
2 0 2 1 2 0 5
6
1 2 3 3 0 0
Sample Output
Case #1: 5
Case #2: 5
题意:
给一个序列,这里面的0可以变成任何整数;问能得到的LIS的长度是多少;
思路:
是题解给的思路,当时一直想不通的是如这样的 4 0 5的序列,0夹在两个相邻整数之间,怎么0就会全部用上了呢?后来才知道可以把0当成后面的那个5啊,所以说0才会全部用上;这是一个关键点,0全部用上,然后求LIS的时候先把0都拿走,当是要给这些0留下空间,怎么办呢?就是每个数减去它前边0的个数,这时两个数的差与之前的差相比,减少了这两个数之间0的个数;所以才保证了既是单调,又让0一定在其中;
AC代码:
/************************************************ ┆ ┏┓ ┏┓ ┆ ┆┏┛┻━━━┛┻┓ ┆ ┆┃ ┃ ┆ ┆┃ ━ ┃ ┆ ┆┃ ┳┛ ┗┳ ┃ ┆ ┆┃ ┃ ┆ ┆┃ ┻ ┃ ┆ ┆┗━┓ ┏━┛ ┆ ┆ ┃ ┃ ┆ ┆ ┃ ┗━━━┓ ┆ ┆ ┃ AC代马 ┣┓┆ ┆ ┃ ┏┛┆ ┆ ┗┓┓┏━┳┓┏┛ ┆ ┆ ┃┫┫ ┃┫┫ ┆ ┆ ┗┻┛ ┗┻┛ ┆ ************************************************ */ #include#include #include #include #include #include #include using namespace std;#define For(i,j,n) for(int i=j;i<=n;i++)#define mst(ss,b) memset(ss,b,sizeof(ss));typedef long long LL;template void read(T&num) { char CH; bool F=false; for(CH=getchar();CH<'0'||CH>'9';F= CH=='-',CH=getchar()); for(num=0;CH>='0'&&CH<='9';num=num*10+CH-'0',CH=getchar()); F && (num=-num);}int stk[70], tp;template inline void print(T p) { if(!p) { puts("0"); return; } while(p) stk[++ tp] = p%10, p/=10; while(tp) putchar(stk[tp--] + '0'); putchar('\n');}const LL mod=20071027;const double PI=acos(-1.0);const int inf=1e9;const int N=1e5+100;const int maxn=(1<<8);const double eps=1e-8;int a[N],sum,d[N],g[N];int main(){ int t,Case=0; read(t); while(t--) { int n,cnt=0,x; read(n); sum=0; For(i,1,n) { read(x); if(x==0)sum++; else a[++cnt]=x-sum; g[i]=inf; } int ans=0; For(i,1,cnt) { int temp=lower_bound(g+1,g+cnt+1,a[i])-g; g[temp]=a[i]; ans=max(ans,temp); } printf("Case #%d: %d\n",++Case,ans+sum); } return 0;}