1510: [POI2006]Kra-The Disks
Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 466 Solved: 272
[Submit][Status][Discuss]
Description
Input
Output
Sample Input
5 6 4 3 6 2 3
3 2 5
Sample Output
所以我们只需要扫一遍序列重新定义一下宽度即可。
譬如样例
5 6 4 3 6 2 3 —> 5 5 4 3 3 2 2
这样这个序列就有序了!
可以二分了!
我们每一次在第一层与上一次选取的层的上一层之间二分出最右边的小于等于当前木块宽度的层即可。
如果没有小于等于的则选取目前可选的最右边的。
1 #include<cstring> 2 #include<cmath> 3 #include<cstdio> 4 #include<algorithm> 5 #include<iostream> 6 7 #define N 300007 8 9 #define Wb putchar(' ') 10 #define We putchar('\n') 11 #define rg register int 12 using namespace std; 13 inline int read() 14 { 15 int x=0,f=1;char ch=getchar(); 16 while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();} 17 while(isdigit(ch)){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();} 18 return x*f; 19 } 20 inline void write(int x) 21 { 22 if(x<0) putchar('-'),x=-x; 23 if (x==0) putchar(48); 24 int num=0;char c[15]; 25 while(x) c[++num]=(x%10)+48,x/=10; 26 while(num) putchar(c[num--]); 27 } 28 29 int n,m; 30 int a[N],b[N]; 31 int sta[N],top; 32 33 int main() 34 { 35 n=read(),m=read(); 36 for(rg i=1;i<=n;i++) 37 a[i]=read(); 38 for(rg i=1;i<=m;i++) 39 b[i]=read(); 40 for(int i=2;i<=n;i++) 41 if(a[i]>a[i-1]) a[i]=a[i-1]; 42 int l,r,la=n+1; 43 for(int i=1;i<=m;i++) 44 { 45 l=1,r=la-1; 46 int ans=r; 47 while(l<=r) 48 { 49 int mid=(l+r)>>1; 50 if(a[mid]<b[i])ans=mid,r=mid-1; 51 else l=mid+1; 52 } 53 la=ans; 54 if(a[ans]<b[i])la--; 55 } 56 write(la); 57 }