2017级算法模拟上机准备篇(序列DP 进阶_1)

进阶版的序列DP 从一道题的优化开始

ModricWang的序列问题

题目描述:给定一个序列,求出这个序列中的最长上升子序列的长度。

这道题的本质还是求解一个最长上升子序列的问题

相对与之前提到过的O(n^2)的算法 我们可以重新整理思路

用O(nlogn)的思路来写,用贪心和二分优化之前的算法

我们设置新的DP数组//dp[i]代表的是当前长度为i的上升子序列的末尾元素的大小

状态转移方程为如果dp[len] < ar[i] 那么就将数ar[i]加到dp数组尾部。

反之,说明可以继续优化显然尾部的元素越小优化的空间就越大,我们利用下界二分查找来进行优化。

    #include <iostream>
    #include <algorithm>
    #include <cstring>
    using namespace std;
    const int maxlen = 1e6;
    int ar[maxlen];
    int dp[maxlen];
    int main(int argc, char *argv[]) {
        int n,i,j,k,len,pos;
        scanf("%d",&n);
        for(i=1;i<=n;i++)
            scanf("%d",&ar[i]);
        len=1;
        dp[1]=ar[1];
         for(i=2;i<=n;i++){
            if(ar[i] > dp[len])
                dp[++len]=ar[i];
                else {
                    pos=lower_bound(dp,dp+len,ar[i])-dp;
                    dp[pos]=ar[i];
                }
        }
        printf("%d\n",len);
        return 0;
    }

ModricWang的序列问题II

题面描述:给定一个序列,求出这个序列中的最长上升子序列的长度,且生成的序列中相邻元素的间隔都是不小于T

这道题在原有题目的基础上增加了长度的限制。

大体解题过程与上一题相同。区别在于对f[]f[] 的操作。没有长度限制的时候,f[]f[] 的更新策略是立即更新。假设间隔为TT,现在由于需要考虑间隔,那么在处理第ii 个元素的时候,就需要看到 前i?Ti?T 个元素生成的f[]f[] ,而不能受到第i?T+1i?T+1 到 i?1i?1 个元素的干扰。因此,考虑如下操作:每次准备更新f[]f[] 时,先不要更新,记录下操作的内容,过TT 步再进行操作,这样就可以让f[]f[] 不再显示当前元素之前TT 步的修改内容,每次更新都不受前TT 步的影响,因此生成的序列中相邻元素的间隔都是不小于TT 的。

详细题解:https://www.cnblogs.com/AlvinZH/p/7978029.html

AlvinZH的最“长”公共子序列

题目描述:给定两个序列,求最少的修改(增加,删除,替换)数,使的两个修改一致。(著名的“编辑距离”问题)

dp[i][j] :记录A的前i个字符与B的前j个字符变成相同需要的最小操作数。

初始化:dp[i][0] = i, dp[0][i] = i。分别代表i次删除or添加操作。

三种操作得到dp[i][j],取其中最小值:

  • 替换:可能不需要替换,所以是dp[i-1][j-1]+Same(A[i-1],B[j-1]);
  • 删除:dp[i-1][j]+1;
  • 添加:dp[i][j-1]+1。

千万不要纠结操作的序列是A还是B!

初始化:

            for (int i = 0; i <= lenA; ++i)
                dp[i][0] = i;//i次删除操作
            for (int i = 0; i <= lenB; ++i)
                dp[0][i] = i;//i次添加操作

状态转移方程:

            for (int i = 1; i <= lenA; ++i) {
                for (int j = 1; j <= lenB; ++j) {
                    dp[i][j] = MIN(dp[i-1][j-1]+Same(A[i-1],B[j-1]), dp[i-1][j]+1, dp[i][j-1]+1);
                    //MIN(替换, 删除, 添加)
                }
            }

原文地址:https://www.cnblogs.com/visper/p/10119624.html

时间: 2024-11-05 22:01:25

2017级算法模拟上机准备篇(序列DP 进阶_1)的相关文章

2017级算法模拟上机准备篇(一)

回顾一下往年的考题知识点: The Last Battle!! 2014级算法期末上机 简单题--I wanna be the 升级者Ⅰ 结构体排序  STL:sort() 简单题--I wanna be the 升级者Ⅱ 二分 :STL : lower_bound () 简单题--Railway Station 数据结构 : 栈操作模拟 简单题--我在东北玩泥巴:博弈论 中等题--零崎的考试:DP 中等题--伪流水线调度:费用流 网络流 中等题--果园连连看:BFS 图论 难题--线段和直线:

2017级算法模拟上机准备篇(归并排序)

归并排序是分治法的一个最经典也是最基础的应用 Divide And Conquer的思想很重要 归并排序的的Divide采用了简单的二分 Conquer采用的是将两个有序数组合并为一个有序数组. 2014-Inverse number:Reborn 逆序数求解 #include <algorithm> #include <iostream> #include <cstring> using namespace std; const int maxlen=1e6 + 10

2017级算法第三次上机-B.SkyLee逛漫展

ALS 一道动态规划最经典的题目 动态规划实质上其实就是表格法,利用表格来记录每个子问题的解. DP所关注的其实是递归 即一个较小问题的解和一个较大问题的状态转移问题. 其次还要关注的其实还是是初始值的设立,这个决定了后续的递推能否顺利的进行. 还有要思考好dp数组所代表的具体的含义 这样在状态转移的过程中 也可以好一点理解. #include <iostream> #include <algorithm> #include <cstring> using namesp

2017级算法第二次上机-C.芸如的入学测试

这道题考察的实际就是一个简单的前缀和问题.值的注意的还是取模的问题.两个数取模,以防万一,出现对负数取模的问题 可以先加上mod然后再对mod取模. 能long long就不int #include <algorithm> #include <iostream> using namespace std; const int maxlen = 1e6 + 10; const int mod = 10007; long long ar[maxlen]; long long prefix

2017级算法第二次上机-E.SkyLee的图书整理

这道题考察了map函数的使用,map最简单的理解就是把一个数映射到一个数.然后使用map也类似hash数组的方法即可 map的头文件是<map> map<int,int> 将一个数映射到一个数 #include <algorithm> #include <iostream> #include <map> using namespace std; int main(){ int n,t,x,i,j,k; while(~scanf("%d

P1-2017级算法第一次上机 A 水水的斐波那契数列

题目描述 相信大家都学过斐波那契数列,虽然很简单,但是斐波那契数列却是很重要的哦,那么让我们来复习一下斐波那契数列吧! 输入 多组数据输入 每行一个整数n (0<n<=30) 输出 对于每组数据,输出一行,为斐波那契数列第n 项的值 输入样例 1 2 3 4 输出样例 1 1 2 3 思路 用一个一维数组f(n)来表示斐波那契数列第n项的值. 则根据定义,后一项等于前两项之和,很容易得到:f(n) = f(n-1) + f(n-2). 有两种做法,递归和循环. 虽然很多人都说递归好理解,但是作

P1-2017级算法第一次上机 G SkyLee在GameStop

题目描述 SkyLee有一天逛街的时候看到一家新开业的GameStop,里面卖各种各样的游戏. 商店里所有的游戏都按游戏名的字典序从小到大排列好了,小的在里面,大的在外面. SkyLee想要把所有的游戏都试玩(买不起游戏只能看看),但是有些问题: 1.游戏只能从展示架的一侧拿出来 2.SkyLee只能拿1个游戏试玩 3.为了不被商店老板发现蹊跷,SkyLee把游戏光盘放回去的时候总要保证每个展示架的游戏仍然按照字典序从小到大排列(小的在里面,大的在外面) 4.SkyLee虽然没钱但是不可能偷游戏

A1-2017级算法第一次上机练习赛 C AlvinZH去图书馆

题目描述 AlvinZH最近在看<冰与火之歌>系列,这天,他又看完了一本书,于是决定去图书馆再借一本.大家知道,在去图书馆的路上,有一条"扯蛋路".大概是这个样子的(秀一波拍照技术): AlvinZH从第一块石砖出发,接下来他可以走到第二块石砖或第三块石砖,有时候走的很不爽,甚至可以直接跨过两个石砖,到达第四块石砖,但是不能连续两次这种操作,因为这样...对身体不好.现在假设有一条含n块石砖的小路,请你计算出AlvinZH从第一块石砖出发有多少种安全的走法. 输入 输入将由

【算法学习笔记】84.序列DP 松弛+代价处理 CODE_VS 1048 石子归并

简单的DP, 处理的时候尽量用len从1到n) , i 从 1 到 len-n] 来遍历. 注意这个时候 len 表示的是从i开头之后接连len个元素组成的序列 for (int i = n-1; i >=1 ; --i){ for (int j = i+1; j <= n ; ++j){ dp[i][j] = INF; for (int k = i; k < j ; ++k){ dp[i][j] = min(dp[i][j], dp[i][k] + dp[k+1][j] + weigh