https://vjudge.net/contest/68966#problem/I
【题解】
http://www.cnblogs.com/kuangbin/archive/2012/08/03/2621110.html
我们可以把由同一个拦截系统负责打下的导弹归为一组。
假设在输入某一系列的导弹高度中,前N个导弹有X组(即需要X个拦截导弹系统),那么第N+1个导弹无非有两种情况:
1.把这个导弹归到X组中的一组,即不增加拦截系统
2.开启新的一组,即增加一个拦截系统
那么什么时候满足1呢? 就是前X组中有一组的最后一个导弹(即高度最低的导弹)比现在这个第N+1的导弹高度还高。
如 5 2 9 1 最后一个导弹高度为1,那么它可以与5 2同一组,也可以与9同一组
那么什么时候满足2呢?就是前X组中没有一组的最后一个导弹(即高度最低的导弹)比现在这个第N+1的导弹高度还高。
如 5 2 9 10 最后一个导弹的高度为10,因此需要一个新的拦截系统。
这两种情况已经分析完了,考虑一些细节,就是在考虑第一种情况时到底应该将 1 放到哪一组?
其实很简单,如 5 2 9 1 7 如果1与9一组,很明显7将要新的拦截系统。而如果1与5 2一组,那么7就可以与9一组,不需要新的拦截系统。
因为1与9一组时,这组高度最低为1,失去了后面高度为6,5这些高度与9一组的机会。因此归于哪一组时,应计算每一组高度最低的导弹与为归组的导弹的高度差,取高度差最小的一组。
最后就可通过有几组来判定需要几个拦截系统。
【Accepted】
1 #include <iostream> 2 #include <stdio.h> 3 #include <cmath> 4 #include <vector> 5 #include <algorithm> 6 #include <set> 7 #include <map> 8 #include <queue> 9 #include <deque> 10 #include <stack> 11 #include <string> 12 #include <bitset> 13 #include <ctime> 14 #include<algorithm> 15 #include<cstring> 16 using namespace std; 17 typedef long long ll; 18 19 int n; 20 const int maxn=3e4+5; 21 const int inf=0x3f3f3f3f; 22 int a[maxn]; 23 int ans[maxn]; 24 int main() 25 { 26 while(~scanf("%d",&n)) 27 { 28 memset(ans,0,sizeof(ans)); 29 for(int i=1;i<=n;i++) 30 { 31 scanf("%d",&a[i]); 32 } 33 int cnt=1; 34 ans[1]=a[1]; 35 for(int i=2;i<=n;i++) 36 { 37 int index=-1; 38 int minn=inf; 39 for(int k=1;k<=cnt;k++) 40 { 41 if(ans[k]>=a[i]&&ans[k]<minn) 42 { 43 minn=ans[k]; 44 index=k; 45 } 46 } 47 if(index==-1) 48 { 49 ans[++cnt]=a[i]; 50 } 51 else 52 { 53 ans[index]=a[i]; 54 } 55 } 56 cout<<cnt<<endl; 57 } 58 return 0; 59 }