标签:sort algorithm tmp 文件 names uniq 序列 span turn
★ 输入文件:lis1.in
输出文件:lis1.out
简单对比
时间限制:1 s 内存限制:256 MB
设有整数序列A[1],A[2],A[3],…,A[m],若存在下标i1<i2<i3<…<in,且A[i1]<A[i2]<A[i3]<…<A[in],则称 序列A[1],A[2],A[3],…,A[m]中有长度为n的上升子序列A[i1] , A[i2] ,A[i3] ,…,A[in]。
请编程计算指定序列的最长上升子序列长度。
第一行一个正整数n(n<1001),表示序列中整数个数;
第二行是空格隔开的n个整数组成的序列。
一个正整数,表示输入文件中整数序列的最长上升子序列的长度。
7
1 7 3 5 9 4 8
4
j
i
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 using namespace std; 6 7 int n; 8 int in[10010],f[10010]; 9 int ans; 10 11 int main(){ 12 scanf("%d",&n); 13 for(int i=1;i<=n;i++) scanf("%d",&in[i]),f[i]=1; 14 for(int i=2;i<=n;i++){ 15 for(int j=1;j<i;j++) 16 if(in[i]>in[j]) f[i]=max(f[i],f[j]+1); 17 ans=max(ans,f[i]); 18 } 19 printf("%d",ans); 20 return 0; 21 }
单调栈优化
从前向后扫描序列列,维护一个单调栈
插?入一个数时,我们在h[] 中二分出一个位置i,使得h[i]<a[k+1]<=h[i + 1],令h[i+1]=a[k + 1] 即可
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 7 int n; 8 int num[10010]; 9 int top; 10 int tmp; 11 12 void add(int t){ 13 if(t>num[top]) num[++top]=t; 14 else{ 15 int ll=1; 16 int rr=top; 17 int mid; 18 while(ll<=rr){ 19 mid=(ll+rr)>>1; 20 if(t>num[mid]) ll=mid+1; 21 else rr=mid-1;//注意-1和+1 22 } 23 num[ll]=t; 24 } 25 return; 26 } 27 28 int main(){ 29 scanf("%d",&n); 30 num[0]=-1; 31 for(int i=1;i<=n;i++) scanf("%d",&tmp),add(tmp); 32 printf("%d",top); 33 return 0; 34 }
树状数组优化
数组离散化并用树状数组维护前缀最大值
1 //实为最长上升子序列 2 #include<iostream> 3 #include<cstdio> 4 #include<cstring> 5 #include<algorithm> 6 using namespace std; 7 8 int n; 9 int in[10010],val[10010]; 10 int len; 11 int b[10010];//b[i]以数字i结尾的子序列最长可以为的值 12 //扫描到in[k]这个位置时,b[i]中只有b[a[k]]会改变 13 //b[a[k]]=max(b[i]+1|i<a[k]) 14 int ans,temp; 15 16 void add(int v,int pos){ 17 for(int i=pos;i<=len;i+=i&(-i)) b[i]=max(v,b[i]); 18 return; 19 } 20 21 int ask(int pos){ 22 int t=0; 23 for(int i=pos;i;i-=i&(-i)) t=max(t,b[i]); 24 return t; 25 } 26 27 int main(){ 28 scanf("%d",&n); 29 for(int i=1;i<=n;i++) scanf("%d",&in[i]),val[i]=in[i]; 30 sort(val+1,val+n+1); 31 len=unique(val+1,val+n+1)-val;//去重 保证最长上升 32 memset(b,0,sizeof(b)); 33 ans=1; 34 for(int i=1;i<=n;i++){ 35 in[i]=lower_bound(val+1,val+len+1,in[i])-val+1;//离散化???高大上 36 temp=ask(in[i]-1)+1; 37 ans=max(ans,temp); 38 add(temp,in[i]); 39 } 40 printf("%d",ans); 41 }
线段树优化
可以用树状数组优化,那么显然可用线段树
然而我码了2K挂掉了,以后再补
标签:sort algorithm tmp 文件 names uniq 序列 span turn
原文地址:http://www.cnblogs.com/sdfzxh/p/6790767.html