最近做题都没怎么发博客,这道题忍不住要发其实也就是因为这道题满分200分……数据强化过了……
想必很多人第一眼看就是O(n2)的做法,但是这是拿不到满分的,所以当然不能那么写(我也不会那么写qwq)
那我们就维护一个队列,每一次将一个新的元素插入队列替换原有元素或者加到队尾即可,很容易实现。
至于第二问最少配置数量,其实就是反过来,即最长上升序列。感性地理解一下就好,其实也可以证明的(我做的时候简单证了一下),在此就不多加解释了。
说实话,感觉这道题不应该是道黄题,它需要的思考方式再某种程度上,我感觉说是道蓝题并不夸张(毕竟O(n2)已经过不了了啊)
那就发代码:
#include<cstdio> #include<iostream> using namespace std; #define maxn 100005 int a[maxn],b[maxn],c[maxn],n,len,str; int main() { int x; while(scanf("%d",&a[++n])!=EOF) continue; n--; //for(int i=1; i<=10; i++) //scanf("%d",&a[++n]); len=1; b[1]=a[1]; for(int i=2; i<=n; i++) { if(a[i]<=b[len]) { b[++len]=a[i]; continue; } else { int l=1,r=len,mid=0; while(l<r) { mid=(l+r)/2; if(b[mid]>=a[i]) l=mid+1; else r=mid; } b[l]=a[i]; } } printf("%d ",len); str=1; c[1]=a[1]; for(int i=2;i<=n;i++) { if(a[i]>c[str]) { c[++str]=a[i]; continue; } else { int p=lower_bound(c,c+str,a[i])-c; c[p]=a[i]; } } printf("%d",str); return 0; }