2016/11/12
我终于打拍了,分数果然好看了很多。
但是并没有A掉第三题
做法:求最长上升子序列
有两个原因:
1.想多了,,以为要从上升和下降中取最优值,,结果还丢分了
2.虽然看过nlogn的最长上升子序列求法 ,但是并没有仔细看,考试的时候自己瞎扯了一个90分算法(实在想不起log是哪里来的了)
看了nlogn的做法后,发现差别在于我没有使用二分查找,改进之后会快很多
首先附上90分的瞎扯代码
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdio> 5 using namespace std; 6 int n,a[200010],f[200010],d[200010]; 7 void inti() 8 { 9 scanf("%d",&n); 10 for(int i=1;i<=n;i++) 11 { 12 scanf("%d",&a[i]); 13 f[i]=200005; 14 } 15 } 16 void work() 17 { 18 int j,sum1=0,sum2=0,ans,s; 19 d[0]=200005; 20 for(int i=1;i<=n;i++) 21 { 22 s=0; 23 for(j=0;j<=sum1;j++)//up 24 { 25 26 // cout<<a[i]<<" "<<f[j]<<" "<<f[j+1]<<endl; 27 if(a[i]>=f[j]&&a[i]<f[j+1]) 28 { 29 f[j+1]=a[i]; 30 s=j+1; 31 break; 32 } 33 } 34 sum1=max(s,sum1); 35 s=0; 36 for(j=0;j<=sum2;j++)//down 其实并不用求下降的部分 37 { 38 if(a[i]<=d[j]&&a[i]>d[j+1]) 39 { 40 d[j+1]=a[i]; 41 s=j+1; 42 break; 43 } 44 45 } 46 sum2=max(s,sum2); 47 } 48 // cout<<sum1<<" "<<sum2<<endl; 49 ans=n-(max(sum1,sum2)); 50 printf("%d",ans); 51 } 52 int main() 53 { 54 freopen("cmi.in","r",stdin); 55 freopen("cmi.out","w",stdout); 56 inti(); 57 work(); 58 return 0; 59 }
然后正确的使用姿势是要二分当前数字可以插入的地方
1 #include<iostream> 2 #include<cstring> 3 #include<algorithm> 4 #include<cstdio> 5 using namespace std; 6 int n,a[200010],f[200010],len; 7 inline int read() 8 { 9 char ch=getchar(); 10 int f=1,x=0; 11 while(!(ch>='0'&&ch<='9')){if(ch=='-')f=-1;ch=getchar();} 12 while(ch>='0'&&ch<='9'){x=x*10+(ch-'0');ch=getchar();} 13 return x*f; 14 } 15 16 void inti() 17 { 18 n=read(); 19 for(int i=1;i<=n;i++) 20 { 21 a[i]=read(); 22 f[i]=200005; 23 } 24 } 25 int find(int i) 26 { 27 int left,right,mid; 28 left=0,right=len; 29 while(left<right) 30 { 31 mid=left+(right-left)/2; 32 if(f[mid]>=a[i]) right=mid; 33 else left=mid+1; 34 } 35 return left; 36 } 37 void work() 38 { 39 int ans,pos; 40 for(int i=1;i<=n;i++) 41 { 42 if(a[i]>f[len]) f[++len]=a[i]; 43 else 44 { 45 pos=find(i); 46 f[pos]=a[i]; 47 } 48 49 } 50 ans=n-len; 51 printf("%d",ans); 52 } 53 int main() 54 { 55 freopen("cmi.in","r",stdin); 56 freopen("cmi.out","w",stdout); 57 inti(); 58 work(); 59 return 0; 60 }
第二题先留坑,并没有看懂标程
以上By Native_carrot