说是第二天,但我昨天太懒没写,今天一起补上吧。

PART ONE : DP复习一

  暑期集训第一天(6-22)题解及总结(于6-23补)

 

 暑期集训第一天(6-22)题解及总结(于6-23补)

 

暑期集训第一天(6-22)题解及总结(于6-23补)

 

 分析:其实这道题本身并不难,就是正反跑一遍最大上升子序列,求一个和总长度最小的差值就行了,但是这道题有一组神奇的数据导致n^3的方法过不去,我正好又不会写二分,于是......

  于是我想趁机说一下二分的有关事项,代码在下面,但是对于可以二分的题我们可以尝试使用lower_bound和upper_bound,我暂时只会用单调上升的,下降的它会返回一些奇奇怪怪的数,他们的功能是这样的,如果我们查找的数在序列中没有,那么他们两个的作用都是返回最后一个小于所查数的位置(注意是位置,在最后要减去数组位置,从1开始的数组要减a+1),如果所查数存在,lower_bound作用不变,upper_bound变为返回位置最大的所查数的位置,比较麻烦,所以以后能手写二分还是手写吧.......

代码:

 1 #include<cstdio>
 2 #include<cstring>
 3 #include<algorithm>
 4 const int N=1e6+10;
 5 using namespace std;
 6 int erfen(int *a,int r,int x){
 7     int l=1,mid;
 8     while(l<=r){
 9         mid=(l+r)>>1;
10         if(a[mid]<=x) l=mid+1;
11         else r=mid-1;
12     }
13     return l;
14 }
15 int a[N],b[N],c[N],sum,ans1,ans2;
16 int main(){
17     //freopen("a.in","r",stdin);
18     int n;
19     scanf("%d",&n);
20     for(int i=1;i<=n;++i){
21         scanf("%d",&a[i]);
22         b[n-i+1]=a[i];
23     }
24     c[1]=a[1];sum=1;
25     for(int i=2;i<=n;++i){
26         if(a[i]>=c[sum]) c[++sum]=a[i];
27         else if(a[i]<c[sum]){
28             int t=erfen(c,sum,a[i]);
29             c[t]=a[i];
30         }
31     }
32     ans1=n-sum;
33     memset(c,0,sizeof(c));sum=1;c[1]=b[1];
34     for(int i=2;i<=n;++i){
35         //for(int j=1;j<=sum;++j) printf("%d ",c[j]); puts("");
36         if(b[i]>=c[sum]) c[++sum]=b[i];
37         else if(b[i]<c[sum]){
38             int t=erfen(c,sum,b[i]);
39             c[t]=b[i];
40         }
41     }
42     ans2=n-sum;
43     printf("%d\n",min(ans1,ans2));
44     return 0;
45 }
麻烦的聚餐

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-09-07
猜你喜欢
  • 2022-12-23
  • 2022-02-05
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
相关资源
相似解决方案