标签:
题意:类似于套娃娃,问最少需要多少个拦截系统。
思路:
假设已经有m个导弹拦截序列
r1:x11>=x12>=x13>=...>=x1n
r1:x21>=x22>=x23>=...>=x2n
.
.
rm:xm1>=xm2>=xm3>=...>=xmn
则必定有有一个序列x1i<x2i<x3i<...<xmi,证明:
若rx中最小比他后边某个序列的所有元素都要大的话,这两个序列必定能合成一个序列。
如r1:8,5,4
r2:3,2,1
因此序列x1i<x2i<x3i<...<xmi的长度就是所求的长度。
另,原序列的最长严格上升序列的长度的就是该序列的长度。证明:
若存在最长严格上升子序列:xj1<xj2<xj3<...<xjk
很明显,则xj2与xj1不可能属于同一个r,后同。故得证。
故原问题就转换成求最长严格上升子序列的长度。
类似的题目还有:http://acm.hdu.edu.cn/showproblem.php?pid=1677
以上结论的证明是本人第一次完全靠自己写的证明,必定有所纰漏,甚至完全错误。写在此并不是为了让看官们背住结论就算了,更希望许多像我一样的菜鸟能够自己动手证明一些东西,这样你对于这个知识点的理解必定会上一层楼。希望大神们指正。
#include<stdio.h> #include<string.h> const int N=1111; int a,d[N]; int main(){ int n,i,ans; while(~scanf("%d",&n)){ d[0]=-1;ans=0; for(i=1;i<=n;i++){ scanf("%d",&a); if(a>d[ans]){ d[++ans]=a; }else{ int l=1,r=ans; while(l<=r){ int mid=(l+r)>>1; if(d[mid]>a) r=mid-1; else l=mid+1; } d[l]=a; } } printf("%d\n",ans); } return 0; }
标签:
原文地址:http://www.cnblogs.com/L-King/p/5763989.html