这个题目还是比较难的(至少对我来说是酱紫的嘤嘤嘤)。。
第一问,看题解好像用的都是DP,但其实可以用二分,求最长不上升子序列,因为只要输出答案,不用输出方案,时间复杂度n leg(n),比DP会快一点。
第二问,暴力枚举,时间复杂度小于n的平方
AC代码:
1 #include<set> 2 #include<map> 3 #include<list> 4 #include<queue> 5 #include<stack> 6 #include<string> 7 #include<cmath> 8 #include<ctime> 9 #include<vector> 10 #include<bitset> 11 #include<memory> 12 #include<utility> 13 #include<cstdio> 14 #include<sstream> 15 #include<iostream> 16 #include<cstdlib> 17 #include<cstring> 18 #include<algorithm>//忒长的头文件,个人建议把会的都写上去,以免出现未调用函数库的的命令 19 using namespace std; 20 int len=1,a,ans; 21 int tt[105],ttt[105];//tt用于第一问,ttt第二问 22 int w(){//二分查找 23 int l=1,r=len; 24 while(l<r){ 25 int mid=(l+r)/2; 26 if(tt[mid]<=a){ 27 r=mid; 28 } 29 else{ 30 l=mid+1; 31 } 32 } 33 return l; 34 } 35 bool pk(){//判断数组是否为空 36 for(int i=1;i<=100;i++){ 37 if(ttt[i]){ 38 return true; 39 } 40 } 41 return false; 42 } 43 int s1(){//这个函数跟下面那个我就不解释了,自己悟去吧。。。 44 for(int i=1;i<=100;i++){ 45 if(ttt[i]){ 46 return ttt[i]; 47 } 48 } 49 } 50 int s2(){ 51 for(int i=1;i<=100;i++){ 52 if(ttt[i]){ 53 return i-1; 54 } 55 } 56 } 57 int main(){//主函数 58 cin>>tt[1]; 59 ttt[1]=tt[1]; 60 int n1=1; 61 int i=2; 62 while((scanf("%d",&a))!=EOF){ 63 ttt[i++]=a; 64 if(a<=tt[len]){//如果小于当前最小的数,就直接放到数组的最后一位 65 tt[++len]=a; 66 } 67 else{//否则就二分 68 tt[w()]=a; 69 } 70 n1++; 71 } 72 cout<<len<<endl; 73 while(pk()){//我最亲爱的暴力 74 int an=s1(); 75 ttt[s2()]=0; 76 for(int i=s2()+1;i<=n1;i++){ 77 if(ttt[i]<=an&&ttt[i]){ 78 an=ttt[i]; 79 ttt[i]=0; 80 } 81 } 82 ans++; 83 } 84 cout<<ans<<endl; 85 return 0; 86 }
好的好的就酱紫,新人开博,望关注哦~~~嘻嘻~~