zoukankan      html  css  js  c++  java
  • 「 COGS 1669 」 神秘的咒语

    题目大意

    这出题人太凉心,居然给我句鸟语。(连我最爱的OI也被鸟语污染了吗)

    下面给大家说说这句鸟语啥意思。不要误会,都是度娘的功劳 QAQ

    之前不是给出了两个伪咒语吗。

    这句鸟语就是说真正的咒语就是两个伪咒语的最长公共上升子序列的长度

    解题思路

    开始的时候用二维的 $dp$ 三层循环的做。只有 $40$ 分。这不对啊,为啥?

    来看看这组样例

    1
    1
    1
    1

    不出意外,你的代码会输出 $0$。但是人都能看出答案应该是 $1$ 。问题出在哪呢?

    再看一下核心部分的代码

    我们发现如果枚举的两个序列的长度都是 $1$ 并且两个数还想等的话。第三重循环就不会进行。

    那么我们的 $f$ 数组也就不会更新,这就导致了错误出现。

    后来我想了想并没有找到妥帖的解决方法,于是决定写压维优化后的最长公共上升子序列。

    大概是这样的

    这样就对了。因为 $f$ 数组得到了更新。

    附上代码

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    using namespace std;
    int T, m1, m2, a[503], b[503], f[503], Ans;
    int main() {
        freopen("codes.in", "r", stdin);
        freopen("codes.out", "w", stdout);
        scanf("%d", &T);
        while (T--) {
            memset(f, 0, sizeof(f));
            Ans = 0;
            scanf("%d", &m1);
            for(int i=1; i<=m1; i++)
                scanf("%d", &a[i]);
            scanf("%d", &m2);
            for(int i=1; i<=m2; i++)
                scanf("%d", &b[i]);
            for(int i=1; i<=m1; i++) {
                int tmp = 0;
                for(int j=1; j<=m2; j++) {
                    if(a[i] > b[j]) tmp = max(tmp, f[j]);
                    if(a[i] == b[j]) f[j] = tmp + 1;
                }
            }
            for(int i=1; i<=m2; i++)
                Ans = max(f[i], Ans);
            printf("%d
    ", Ans);
        }
        fclose(stdin); fclose(stdout);
        return 0;
    }
  • 相关阅读:
    windows下安装mysql-5.7.11-winx64
    memset库函数
    [转]全面解析《嵌入式程序员应该知道的16个问题》
    Cent OS 7 下 Redis 5.0.5 安装与配置
    SVN+TortoiseSVN的Windows版安装和配置
    工具和环境--目录(随时更新)
    Linux安装和配置Nodejs和NPM
    Windows10命令提示符窗口大小导致执行效率不同问题
    Windows安装Nodejs和npm以及创建项目
    WebStorm 2019.3.2安装与配置
  • 原文地址:https://www.cnblogs.com/bljfy/p/9581507.html
Copyright © 2011-2022 走看看