题目中的严格二字,表示的意思是不允许≥或者是≤的情况出现,只允许>的情况以及<的情况
经典问题是NOIP合唱队形,在这个题目中,既求了最长上升子序列,也求了最长下降子序列
其最终的结果由两个子序列的结果共同得来
我们给出实现方法:
//最长上升子序列
for(int i=1;i<=n;i++)
for(int j=i-1;j>=0;j--)
if(a[j]<a[i])
f1[i]=max(f1[i],f1[j]+1);
//最长下降子序列
for(int i=n;i>=1;i--)
for(int j=i+1;j<=n+1;j++)
if(a[j]<a[i])
f2[i]=max(f2[i],f2[j]+1);
以最长上升子序列为例,其转移方程为:f(i)=max(f(i),f(j)+1),并且当a[i]>a[j]时进行转移
在实现的时候,一定要控制好下标,以及边界处理,以上代码的边界处理是没有问题的
下面给出合唱队形这道题的代码:
1 #include<cstdio>
2 #include<algorithm>
3 using namespace std;
4 const int maxn=105;
5 int n;
6 int ans;
7 int a[maxn];
8 int f1[maxn],f2[maxn];
9 int main()
10 {
11 scanf("%d",&n);
12 for(int i=1;i<=n;i++)
13 scanf("%d",&a[i]);
14 for(int i=1;i<=n;i++)
15 for(int j=i-1;j>=0;j--)
16 if(a[j]<a[i])
17 f1[i]=max(f1[i],f1[j]+1);
18 for(int i=n;i>=1;i--)
19 for(int j=i+1;j<=n+1;j++)
20 if(a[j]<a[i])
21 f2[i]=max(f2[i],f2[j]+1);
22 for(int i=1;i<=n;i++)
23 ans=max(ans,f1[i]+f2[i]);
24 ans=n-ans+1;
25 printf("%d\n",ans);
26 return 0;
27 }
来源:https://www.cnblogs.com/aininot260/p/9305962.html