第一问即经典的最长不下降子序列问题,可以用一般的DP算法,也可以用高效算法,但这个题的数据规模不需要。
用a[x]表示原序列中第x个元素,b[x]表示长度为x的不下降子序列的长度,。当处理第a[x]时,可查找它可以连接到长度最大为多少的不下降子序列后(即与部分b[x]比较)。假设可以连到长度最大为maxx的不下降子序列后,则b[x]:=maxx+1。b数组被赋值的最大值就是第一问的答案。
第二问用贪心法即可。每颗导弹来袭时,使用能拦截这颗导弹的防御系统中上一次拦截导弹高度最低的那一套来拦截。若不存在符合这一条件的系统,则使用一套新系统。
1 #include<iostream>
2 #include<cstdio>
3 #include<cstring>
4 #include<cmath>
5 using namespace std;
6 const int MAXN=21;
7 const int maxn=0x7fffffff;
8 int a[MAXN][4];
9 int now=1;
10 int xt[MAXN];
11 int now2=0;// 系统的数量
12 int main()
13 {
14 while(cin>>a[now][1])
15 {
16 int flag=0;
17 for(int i=1;i<=now2;i++)
18 {
19 if(xt[i]>=a[now][1])
20 {
21 flag=1;
22 xt[i]=a[now][1];
23 break;
24 }
25
26 }
27 if(flag==0)
28 {
29 now2++;
30 xt[now2]=maxn;
31 xt[now2]=a[now][1];
32 }
33 a[now][2]=1;
34 a[now][3]=0;
35 now++;
36 }
37 for(int i=now-2;i>=1;i--)
38 {
39 int l=0;
40 int k=0;
41 for(int j=i+1;j<=now-1;j++)
42 {
43 if(a[j][1]<a[i][1]&&a[j][2]>l)
44 {
45 k=j;
46 l=a[j][2];
47 }
48 }
49 if(l>0)
50 {
51 a[i][2]=l+1;
52 a[i][3]=k;
53 }
54
55 }
56 int ans1=0;
57 for(int i=1;i<=now-1;i++)
58 {
59 ans1=max(a[i][2],ans1);
60 }
61 printf("%d\n",ans1);
62 printf("%d",now2);
63 return 0;
64 }