首页 > 编程语言 >算法学习笔记( 一)(1)动态规划(LIS)

算法学习笔记( 一)(1)动态规划(LIS)

时间:2023-07-05 11:45:40浏览次数:130  
标签:ch 结尾 int tail len 算法 笔记 LIS

题目链接:https://www.acwing.com/problem/content/897/


讲解

动态规划问题具有三个特质:

  • 子问题重叠: 即子问题是相互之间依赖的 这个子问题在之后可能被反复使用
    (此条件并非必要条件 但失去它也就没有优化作用了)
  • 最优化原理: 此问题可以通过子问题的代表元素(最优解)来求出 这就也称作满足了最优子结构
  • 无后效性: 此状态一经确定 不受以后决策影响

通过例子来慢慢解释
\(LIS\): 给定一个长度为\(N\)的数列,求数值严格单调递增的子序列的长度最长是多少。

我们可以写出暴力程序:

int n, a[105];
int k[105], ans;
void dfs(int len) {
   if (len > ans) {
      ans = len;
      // 如果需要方案,记录 {A[k[1]], A[k[2]], ..., A[k[len]]}
   }
   // {k[1], k[2], ..., k[len]}
   // B = {A[k[1]], A[k[2]], ..., A[k[len]]}
   for (int i = k[len] + 1; i <= n; i++)
      if (a[i] > a[k[len]]) {
         k[len + 1] = i;
         dfs(len + 1);
      }
}
k[0] = 0, a[0] = -(1<<30);
dfs(0);

我们可以发现 对于每一个\(dfs\) 只用到了\(k[len]\)这个结尾数
于是我们可以不用记录\(k[]\) 直接记录上一个数

void dfs(int len, int tail) {
   if (len > ans) {
      ans = len;
   }
   for (int i = tail + 1; i <= n; i++)
      if (a[i] > a[tail])
         dfs(len + 1, i);
}
a[0] = -(1<<30);
dfs(0, 0);

于是这时候我们就发现了 我们总是去调用\(tail\)值同样的函数

if a[] = {1, 7,3, 4, 5};
调用了两个函数 k[]为
{1,3,4}
和 {3,4}

那么我们发现 其实没有必要调用{3, 4} 无论后面接什么数 他一定不会比{1, 3, 4}优
但是他们的\(tail\)相同 \(len\)不同 我可不可以把他们归为一类 只要调用到\(tail\)值为4 那他以\(4\)结尾\(LIS\)最大就是\(3\)(最终问题不就是求最大值吗)
那么我们需要换一下枚举方法
那么此时的答案 是不是就是 每个以\(a[i]\)为结尾的最长上升子序列的长度的最大值 的 最大值


由此:
新状态:结尾下标
状态总数:\(n\)
\(f[i]\)表示以\(a[i]\)为结尾的最长上升子序列的长度

显然子问题之间满足最优子结构性质 并且
按照1-n枚举是拓扑序(1.不可能有环(反证) 2.不可能由后面的更新前面的(LIS定义))

那么当枚举到i时 他只能被前面的更新 但是前面的更新完了 所以他就是最大值
(这就是\(f[i]\)求法 以\(i\)为结尾的\(LIS\) 上一个数一定是 \(1 - i - 1\)结尾的满足条件LIS 最大值 通过前面数更新)
然后再去遍历拓扑图 看看后面能接什么 枚举就行
由此

f[0] = 0;
for (int i = 0; i < n; i++) // i: 结尾下标
   for (int j = i + 1; j <= n; j++) // 下一个数
      if (a[j] > a[i]) f[j] = max(f[j], f[i] + 1);

也可以枚举这个\(f[i]\)是由什么转移来的

f[0] = 0;
for (int i = 1; i <= n; i++)
   if (int j = 0; j < i; j++) // 前一个数
      if (a[j] < a[i]) f[i] = max(f[i], f[j] + 1);

完整代码

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

using namespace std;

const int N = 1010;

int w[N], n, f[N];

void read(int &r)
{
    int f = 1, x = 0;
    char ch = getchar();
    while (ch < '0' || ch > '9')
    {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    while (ch >= '0' && ch <= '9')
	{
		x = x * 10 + ch - '0';
		ch = getchar();
	}
	r = f * x;
}

int main()
{
	read(n);
	for (int i = 1; i <= n; i ++ ) read(w[i]);
	
	for (int i = 1; i <= n; i ++ )
	{
	    f[i] = 1;
		for (int j = 1; j < i; j ++ )
			if (w[j] < w[i])
				f[i] = max(f[i], f[j] + 1);
	}
	int res = 0;
	for (int i = 1; i <= n; i ++ )
		res = max(res, f[i]);
	
	printf("%d\n", res);
	
	return 0;
}

标签:ch,结尾,int,tail,len,算法,笔记,LIS
From: https://www.cnblogs.com/qinyiting/p/17528110.html

相关文章

  • Python基础语法--课程笔记
    Smiling&Weeping----我的心是旷野的鸟,在你的眼睛里找到了它的天空定义和使用类:1.声明类:class类名:成员变量,成员函数2.定义类的对象:对象名=类名()3.成员变量:  公有变量私有变量__xxx4.构造函数: ......
  • 【AI新趋势期刊#2】AI发明计算机算法,如何给大模型排行,照片秒变二维码,视频一键动漫风
    前言每天都要浏览大量AI相关新闻,是不是感到信息量爆炸,有效信息少?这么多新产品和新工具,到底哪些是真正是有价值的,哪些只是浮躁的一时热点?想参与AI产品和工具的开发,从哪里能够获得大量的灵感和思路?我会把AI相关的新趋势、新想法、新思路,和成熟AI产品、工具、模型等整理在这里,帮......
  • 论文阅读:Segment Anything之阅读笔记
    引言论文:SegmentAnything是Meta出的图像语义分割的算法。这个算法因其强大的zero-shot泛化能力让人惊艳,这不抽空拿来学习了一下。该算法的代码写得很清楚、简洁和规范,读来让人赏心悦目。推荐去看源码,很有意思。本篇文章,将以问答形式来解读阅读过程中遇到的困惑,想来这种方式效......
  • 【Oracle】行转列的函数wm_concat,listagg,xmlagg,pivot以及动态行转列
    【Oracle】行转列的几种情况表的数据如下朴实无华的函数1.wm_concat使用格式:select分组字段,wm_concat(要转换的列名)from表名groupby分组字段实例:selectit.Code,wm_concat(it.inv)fromttt20230705itgroupbyit.Code2.listagg()withingroup()使用格式:......
  • 未来数据定时刷新——从zset中获取预设时间内的任务添加到list中
    未来数据定时刷新——实现步骤:定时任务/每分钟————》未来数据的keys————》按照分值查询zset,判断数据是否到期——到期》同步到Redis中的list 1、如何获取zset中所有的key?keys模糊匹配,future。效率低SCNA命令:SCAN命令是一个基于游标的迭代器,SCAN命令......
  • 代码随想录算法训练营第二十四天| 491.递增子序列 46.全排列 47.全排列 II
     491.递增子序列 此题的难点:1,前提需要保留原有顺序2,保证递增3,保证去重注意:去重一定要有set的同时保证有顺序代码:1voidfindSubsequences_trackBack(vector<int>&nums,intstartIndex,vector<int>&path,vector<vector<int>>&result)2{3if(path.size(......
  • 方芳:非物质文化遗产学习整理笔记(10-13)
    武汉市江夏路桥工程有限公司中央财经大学 经济管理学院    方   芳    15927602711第十章 传统技艺、技能与技术传统技艺、技能与技术是指劳动人民在生产和生活中创追出的知识和技艺、技能和技术,它包括传统技艺、传统体育、游艺与杂技、传统医药等。......
  • 34最优化算法
    好的,以下是常见最优化算法的公式,使用Markdown格式进行展示:1.梯度下降法(GradientDescent):参数更新公式:\(\theta^{(t+1)}=\theta^{(t)}-\alpha\nablaJ(\theta^{(t)})\)2.随机梯度下降法(StochasticGradientDescent):参数更新公式:\(\theta^{(t+1)}=\theta^{(t)}-......
  • [ SQL笔记 ] 基础语法篇
    SQL基础篇 一:普通查询语句:SELECT 语法:SELECTcolumn1,column2,...FROMtable_name; 或SELECT*FROMtable_name; 示例:SELECT*FROMWebsites;SELECTname,countryFROMWebsites; 二:去重查询语句:SELECT DISTINCT  ......
  • m基于细菌觅食优化的DSR网络路由协议优化算法matlab仿真
    1.算法仿真效果matlab2022a仿真结果如下:    2.算法涉及理论知识概要        移动自组网(MobileAdHocNetwork,简称MANET)是一种无需基础设施支持的网络,它由一组移动的节点组成,这些节点可以自组织形成一个网络,实现数据的传输和共享。由于MANET是一种去中心化......