首页 > 其他分享 >P11187 配对序列

P11187 配对序列

时间:2024-10-13 18:59:58浏览次数:5  
标签:last int else P11187 序列 配对 末尾

P11187 配对序列 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn)

考虑DP,看注释,时间复杂度 \(O(n)\)。非最优思路。

#include <iostream>
#include <cstdio>
#include <algorithm>

using namespace std;

const int N = 500010;

int f[N][2]; // f[i][0/1] 前i个里面的最大子序列长度,0/1 表示两个不同末尾且0大于1 
int g[N][2]; // 表示对应f的末尾,0/1不同
int n, m;
int a[N], b[N]; // b[i]表示当前数值为i的数的下标,用于求出last数组
int last[N]; // last[i]表示与a[i]相同的上一个数的下标,用于加快DP

/* 对于 f[i] 来说要么使用当前a[i]作为序列,要么不用。
如果使用a[i],那么它一定先配对last[i],那么就用f[v = last[i] - 1]递推过来,前提f[v]所选的末尾和a[i]不同.如果不用就继承f[i-1].转移方程为 f[i] = max(f[i - 1], f[last[i] - 1] + 2);
因为非f[v]的选法可能可以和a[i]拼接,而f[v]选法不可,导致答案有漏,为了转移全面,于是记录f[i][0/1]两个末尾不同,且f[i][0]>=f[i][1],把漏掉的补上 就出现以下代码

*/
int main()
{
    cin >> n;
    
    for (int i = 1; i <= n; i ++ )
    {
        scanf("%d", &a[i]);
        if (b[a[i]]) last[i] = b[a[i]];
        b[a[i]] = i;
    }
    
    for (int i = 1; i <= n; i ++ )
    {
        f[i][0] = f[i - 1][0];
        g[i][0] = g[i - 1][0];
        
        f[i][1] = f[i - 1][1];
        g[i][1] = g[i - 1][1];
        
        int v = last[i] - 1;
        if (last[i] > 0) 
        {
            if (g[v][0] != a[i]) // 第一个可以
            {
                if (f[i][0] < f[v][0] + 2) 
                {
                    f[i][1] = f[i][0];
                    g[i][1] = g[i][0];
                    f[i][0] = f[v][0] + 2;
                    g[i][0] = a[i];
                }
                else if (f[i][1] < f[v][0] + 2) 
                {
                    f[i][1] = f[v][0] + 2;
                    g[i][1] = a[i];
                }
                else if (f[i][1] == f[v][0] + 2 && g[i][1] == g[i][0])
                {
                    g[i][1] = a[i];
                }
            }
            
            if (g[v][1] != a[i])
            {
                if (f[i][0] < f[v][1] + 2) 
                {
                    f[i][1] = f[i][0];
                    g[i][1] = g[i][0];
                    f[i][0] = f[v][1] + 2;
                    g[i][0] = a[i];
                }
                else if (f[i][1] < f[v][1] + 2)
                {
                    f[i][1] = f[v][1] + 2;
                    g[i][1] = a[i];
                }
                else if (f[i][1] == f[v][1] + 2 && g[i][1] == g[i][0])
                {
                    g[i][1] = a[i];
                }
            }
        }
        if (f[i][1] > f[i][0]) 
        {
            swap(f[i][1], f[i][0]);
            swap(g[i][1], g[i][0]);
        }
        
    }
    cout << f[n][0] << endl;
    
    return 0;
}

标签:last,int,else,P11187,序列,配对,末尾
From: https://www.cnblogs.com/blind5883/p/18462762

相关文章

  • DAY31 ||贪心算法基础 | 455.分发饼干 |376.摆动序列 |53.最大子数组和
    贪心算法基础贪心算法是一种在求解问题时采取逐步构建解决方案的算法策略。它通过在每一步选择在当前看来最优的选择(即“贪心”选择),希望通过局部最优解的累积得到全局最优解。贪心算法的核心思想局部最优:每一步都选择在当前状态下最优的选择,不考虑后续步骤可能带来的影响。......
  • DAY30||491.非递减子序列 |46.全排列 |47.全排列Ⅱ
    491.非递减子序列题目:491.非递减子序列-力扣(LeetCode)给定一个整型数组,你的任务是找到所有该数组的递增子序列,递增子序列的长度至少是2。示例:输入:[4,6,7,7]输出:[[4,6],[4,7],[4,6,7],[4,6,7,7],[6,7],[6,7,7],[7,7],[4,7,7]]说明:给定数组......
  • 第2关:寻找一个序列中的第K小的元素(即第k小元问题)
    [TOC]寻找一个序列中的第K小的元素(即第k小元问题)对于给定的含有n(n<=100)元素的无序序列,求这个序列中第k(1≤k≤n)小的元素。任务描述本关任务:编写一个能计算数组中的第k小的元素的小程序。相关知识假设无序序列存放在a[0…n-1]中,若将a递增排序,则第k小的元素为a[k-1]。......
  • 第108天:免杀对抗-Python&混淆算法&反序列化&打包生成器&Py2exe&Nuitka
    知识点#知识点:1、Python-对执行代码做文章2、Python-对shellcode做文章3、Python-对代码打包器做文章#章节点:编译代码面-ShellCode-混淆编译代码面-编辑执行器-编写编译代码面-分离加载器-编写程序文件面-特征码定位-修改程序文件面-加壳花指令-资源代码加载面-Dll反......
  • idea-java序列化serialversionUID自动生成
    简介java.io.Serializable是Java中的一个标记接口(markerinterface),它没有任何方法或字段。当一个类实现了Serializable接口,那么这个类的对象就可以被序列化和反序列化。序列化是将对象的状态转换为字节流的过程,这样可以方便地将对象存储到文件中或者通过网络传输。反序列化......
  • 时间序列预测(一)——线性回归(linear regression)
    目录一、原理与目的1、线性回归基于两个的假设:2、线性回归的主要目的是:二、损失函数(lossfunction)1、平方误差损失函数(忽略了噪声误差)2、均方误差损失函数三、随机梯度下降(通过不断地在损失函数递减的方向上更新参数来降低误差。)四、代码实现参考文章:机器学习—线......
  • sql server 2012提示:评估期已过 的解决办法 附序列号
    sqlserver2012版本序列号如下:MICROSOFTSQLSERVER2012企业核心版激活码序列号:FH666-Y346V-7XFQ3-V69JM-RHW28MICROSOFTSQLSERVER2012商业智能版激活码序列号:HRV7T-DVTM4-V6XG8-P36T4-MRYT6MICROSOFTSQLSERVER2012开发版激活码序列号:YQWTX-G8T4R-QW4XX-BV......
  • 【python-数据分析】pandas时间序列处理
    1.timestamp1.1创建timestamp自定义timestamp语法:pd.Timestamp(ts_input,tz,year,month,day,hour,minute,second,microsecond,nanosecond,tzinfo)代码示例:importpandasaspdimportpytz#当ts_input为字符串时,一般要与tz参数搭配使用timestamp=pd.Timestamp(ts......
  • 不安全的反序列化
    不安全反序列化是一种针对Web应用程序和API的许多攻击链的一部分的漏洞,。易受攻击的应用程序将在不验证数据的情况下加载数据,从而允许攻击者操纵反序列化过程并执行恶意代码。虽然不安全反序列化并不总是作为独立漏洞报告,但可能会对网络安全造成严重后果,包括远程代码执行(RCE......
  • 代码随想录Day23 | LeetCode 455. 分发饼干、LeetCode 53. 最大子数组和、LeetCode 37
    LeetCode455.分发饼干贪心就是干classSolution:deffindContentChildren(self,g:List[int],s:List[int])->int:g.sort(reverse=True)s.sort(reverse=True)i=j=0res=0whilei<len(g)andj<len(......