以下选自官方题解:
考虑困难的需求数量,我们将覆盖这些困难,
然后我们将提出新的问题,并准备新的问题来覆盖其他需求。
很明显,如果我们决定满足从n中抽取i的要求,那么最好采用那些复杂性最小的要求。
让我们把最难的问题简化成最简单的要求。
如果一切顺利,我们用n-i更新答案。
时间复杂度为O(n^2),空间复杂度为O(n)。
有一个复杂度为O(n+m)的解,希望读者认真探究。
代码:
1 #include <bits/stdc++.h>//万能头文件 2 3 using namespace std;//使用标准名字空间 4 5 inline int read()//快速读入 6 { 7 int f=1,x=0; 8 char c=getchar(); 9 10 while(c<'0' || c>'9') 11 { 12 if(c=='-')f=-1; 13 c=getchar(); 14 } 15 16 while(c>='0' && c<='9') 17 { 18 x=x*10+c-'0'; 19 c=getchar(); 20 } 21 22 return f*x; 23 } 24 25 int a[3005],b[3005],n,m,ans;//定义变量 26 27 int main() 28 { 29 n=read(),m=read(); 30 31 for(register int i=0; i<n; i++)a[i]=read(); 32 33 for(register int i=0; i<m; i++)b[i]=read(); 34 35 ans=n;//初始化答案 36 37 if(ans>m)//如果答案比已有复杂度的个数还多 38 { 39 ans=m;//就把答案设为已有复杂度个数 40 } 41 42 for(int i=ans; i>=0; i--)//开始枚举 43 { 44 int flag=1;//设置标记 45 46 for(int j=0; j<i; j++)//枚举位置在i前面的复杂度 47 { 48 if(a[j]>b[m-i+j])//如果不满足条件 49 { 50 flag=0;//就标记为不行 51 } 52 } 53 54 if(flag)//如果当前是一个可行方案 55 { 56 printf("%d ",n-i);//那么直接输出 57 58 return 0;//结束 59 } 60 } 61 }