题解 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的原因

CODE

#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;
}
posted @ 2019-01-27 16:28  加固文明幻景  阅读(3)  评论(0编辑  收藏  举报  来源