题解 P1091 【合唱队形】

看到这题就写了这样一份代码,然后就AC了。

发现题解好像都跟我不一样欸。因为我是乱搞的

研究了半天终于明白了自己是怎么搞得了:

f1[i]f2[i]分别表示i为结尾的最长上升子序列i为开头的最长上升子序列。(这点与其他题解无异)

而我的代码与其他题解的不同点就在于:

以求f1[i]为例

  • 其他题解是这样写的:

    for(int i=1;i<=n;i++) { for(int j=1;j<i;j++) { if(a[i]>a[j] && f1[j]+1<f1[i]) { f1[i]=f[j]+1; } } }

    这样写是用i前面的最长上升子序列来更新f1[i]的值。

  • 而我是这样写的:

    for(int i=1; i<=n; i++) { for(int j=i+1; j<=n; j++) { if(a[i]<a[j] && f1[i]+1>f1[j]) { f1[j]=f1[i]+1; } } }

    这样写则是用f1[i]的值来更新i后面的最长上升子序列的值

f2的求法也是同理的。

这就是我AC的原因

1|0CODE:

#include <cstdio> int n,f1[110],f2[110],a[110]; int main(void) { scanf("%d",&n); for(int i=1; i<=n; i++) { f1[i]=f2[i]=1; scanf("%d",&a[i]); } for(int i=1; i<=n; i++) { for(int j=i+1; j<=n; j++) { if(a[i]<a[j] && f1[i]+1>f1[j]) { f1[j]=f1[i]+1; } } } for(int i=n; i>=1; i--) { for(int j=i-1; j>=1; j--) { if(a[i]<a[j] && f2[i]+1>f2[j]) { f2[j]=f2[i]+1; } } } int ans=-0x7fffffff; for(int i=1; i<=n; i++) { ans=ans>f1[i]+f2[i]?ans:f1[i]+f2[i]; } printf("%d",n-ans+1); return 0; }

__EOF__

本文作者Kdlyh
本文链接https://www.cnblogs.com/kdlyh/p/17776987.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是博主的最大动力!
posted @   加固文明幻景  阅读(4)  评论(0编辑  收藏  举报  
相关博文:
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下
点击右上角即可分享
微信分享提示