首页 > 编程语言 >(算法)等差数列划分————<动态规划>

(算法)等差数列划分————<动态规划>

时间:2024-10-17 20:48:44浏览次数:3  
标签:nums int sum 元素 算法 等差数列 动态 dp

1. 题⽬链接:413.等差数列划分

2. 题⽬描述:

3. 解法(动态规划):

算法思路:

1. 状态表⽰:

由于我们的研究对象是「⼀段连续的区间」,如果我们状态表⽰定义成[0, i] 区间内⼀共有多 少等差数列,那么我们在分析dp[i] 的状态转移时,会⽆从下⼿,因为我们不清楚前⾯那么多 的「等差数列都在什么位置」。所以说,我们定义的状态表⽰必须让等差数列「有迹可循」,让状 态转移的时候能找到「⼤部队」。因此,我们可以「固定死等差数列的结尾」,定义下⾯的状态表 ⽰:

dp[i] 表⽰必须「以i 位置的元素为结尾」的等差数列有多少种。

2. 状态转移⽅程:

我们需要了解⼀下等差数列的性质:如果a b c 三个数成等差数列,这时候来了⼀个d ,其 中b c d 也能构成⼀个等差数列,那么a b c d 四个数能够成等差序列吗?

答案是:显然 的。因为他们之间相邻两个元素之间的差值都是⼀样的。有了这个理解,我们就可以转⽽分析我们 的状态转移⽅程了。 对于dp[i] 位置的元素nums[i] ,会与前⾯的两个元素有下⾯两种情况:

        i. nums[i - 2], nums[i - 1], nums[i] 三个元素不能构成等差数列:那么以 nums[i] 为结尾的等差数列就不存在,此时dp[i] = 0 ; 

        ii. nums[i - 2], nums[i - 1], nums[i] 三个元素可以构成等差数列:那么以 nums[i - 1] 为结尾的所有等差数列后⾯填上⼀个 nums[i] 也是⼀个等差数列,此时 dp[i] = dp[i - 1] 。但是,因为 nums[i - 2], nums[i - 1], nums[i] 三 者⼜能构成⼀个新的等差数列,因此要在之前的基础上再添上⼀个等差数列,于是 dp[i] = dp[i - 1] + 1 。

综上所述:状态转移⽅程为: 当: nums[i - 2] + nums[i] != 2 * nums[i - 1] 时, dp[i] = 0  当: nums[i - 2] + nums[i] == 2 * nums[i - 1] 时, dp[i] = 1 + dp[i - 1]

3. 初始化:

由于需要⽤到前两个位置的元素,但是前两个位置的元素⼜⽆法构成等差数列,因此dp[0] = dp[1] = 0 。

4. 填表顺序:

毫⽆疑问是「从左往右」。

5. 返回值:

因为我们要的是所有的等差数列的个数,因此需要返回整个dp 表⾥⾯的元素之和。 

C++算法代码: 

class Solution
{
public:
	int numberOfArithmeticSlices(vector<int>& nums)
	{
		// 1. 创建 dp 表 
		// 2. 初始化 
		// 3. 填表 
		// 4. 返回结果 
		int n = nums.size();
		vector<int> dp(n);
		int sum = 0;
		for (int i = 2; i < n; i++)
		{
			dp[i] = nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2] ? dp[i
				- 1] + 1 : 0;
			sum += dp[i];
		}
		return sum;
	}
};

Java算法代码:

class Solution
{
	public int numberOfArithmeticSlices(int[] nums)
	{
		// 1. 创建 dp 表 
		// 2. 初始化 
		// 3. 填表 
		// 4. 返回值 
		int n = nums.length;
		int[] dp = new int[n];
		int sum = 0;
		for (int i = 2; i < n; i++)
		{
			dp[i] = nums[i] - nums[i - 1] == nums[i - 1] - nums[i - 2] ? dp[i
				- 1] + 1 : 0;
			sum += dp[i];
		}
		return sum;
	}
}

标签:nums,int,sum,元素,算法,等差数列,动态,dp
From: https://blog.csdn.net/2301_79580018/article/details/143027264

相关文章

  • 图论day64 :最短路径算法 | SPFA(Bellman_ford的队列优化版)、城市间货物运输 I、Ⅱ、Ⅲ
    图论day64:最短路径算法|SPFA(Bellman_ford的队列优化版)、94.城市间货物运输I(卡码网)【SPFA算法+邻接表优化】、95.城市间货物运输II(判断负权回路)、96.城市间货物运输III【已知有负权回路,该如何计算】、Bellman_ford算法思维导图汇总SPFA(Bellman_ford的队列优化版)94......
  • 从单细胞和空间转录组学推断模式驱动的细胞间流动(Flowsig)--生信算法笔记
    **Inferringpattern-drivingintercellularflowsfromsingle-cellandspatialtranscriptomics**Almet,A.A.,Tsai,YC.,Watanabe,M.etal.Inferringpattern-drivingintercellularflowsfromsingle-cellandspatialtranscriptomics.NatMethods21,1806......
  • 大数据传播模型与算法——影响力最大化
    【大数据网络传播模型和算法-陈卫】——影响力最大化【持续更新】本人当前研究方向为影响力最大化(基于机器学习的组合优化算法)。目前在学习陈卫编著的《大数据传播模型与算法》,该系列会定期分享影响力最大化的学习内容(持续更新…),希望大家能够一起交流学习!前言什么是影响?......
  • 【关联规则挖掘算法‌】基于模式增长的关联规则挖掘算法
    目录一、基于模式增长的关联规则挖掘算法概述二、基于模式增长的关联规则挖掘算法优缺点和改进2.1  基于模式增长的关联规则挖掘算法优点2.2  基于模式增长的关联规则挖掘算法缺点2.3  基于模式增长的关联规则挖掘算法改进三、基于模式增长的关联规则挖掘算法编程......
  • 雪花算法------用于生成数据库中的主键、消息队列的消息ID等的算法-----算法特点,id结
    雪花算法(SnowflakeAlgorithm)是一种由Twitter公司开发的分布式ID生成算法,用于在分布式系统中生成全局唯一的ID。这种算法非常适合需要高并发、低延迟以及大量唯一ID生成的应用场景,比如数据库中的主键、消息队列的消息ID等。雪花算法的主要特点包括:唯一性:生成的ID在全球范围内......
  • 算法
    1.常见算法点击查看代码*冒泡排序:重复数列,一次比较两个元素,如果顺序错误就交换*选择排序:每次选择未排序的部分最大或最小元素,放到已排序末尾*插入排序:将未排序的元素逐个插入到已排序部分的合适位置*快速排序:选择一个基准元素,将小于的放左边,大的放右边,再对左右递归进行......
  • 【Echarts 实战指南】仪表盘接收动态数据,小白轻松上手
    ECharts仪表盘因其强大的数据可视化功能而被广泛应用于多种场景。性能监控、生产监控、设备监控等等template<template><a-cardshadow="none"style="margin:20px0020px"title=""> <divclass="item"ref="chartContainer8"><......
  • 图论中的最小生成树算法
    错题考察的知识点是图论中的最小生成树算法,特别是Prim算法和Kruskal算法。这两种算法都是用来寻找无向连通图中的最小生成树的。最小生成树是指连接图中所有顶点的边的集合,且这些边的总权重最小,同时保证任意两个顶点之间都是连通的。Prim算法:原理:从一个任意顶点开始,逐步增加新......
  • 基于BP神经网络的CoSaMP信道估计算法matlab性能仿真,对比LS,OMP,MOMP,CoSaMP
    1.算法仿真效果matlab2022a仿真结果如下(完整代码运行后无水印):   仿真操作步骤可参考程序配套的操作视频。 2.算法涉及理论知识概要        LS估计法实现方式较为简单,其估计过程没有考虑实际信道的噪声因素。因此,特别当毫米波MIMO信道干扰较大时,其估计性能较......
  • 常用手撕非算法题
    一.带定时器和锁的LRU缓存#include<iostream>#include<unordered_map>#include<chrono>#include<mutex>#include<thread>usingnamespacestd;classLRUCache{public:typedefstructNode{//双向链表节点intkey;//在哈希中的键值,用......