未见过类型题每周总结(个人向)

news2024/12/24 5:45:20


1.DP40 小红取数

题目

解析 

一道01背包的衍生问题,我们可以按照它的思路定义数组dp[i][j],表示前i个数中%k为j的最大和。为什么设置未%k的最大和呢?是因为当两个数分别%k,如a%k=x,b%k=y。那么(a+b)%k==(x+y)%k。接下来推动态转移方程,取第i个数时dp[i][j]=dp[i-1][j-arr[i]%k]+arr[i],不取第i个数时dp[i][j]=dp[i-1][j],但是如果j-arr[i]%k<0,那么数组会越界,和普通的01背包不同,我们这里就算它小于0,也是存在意义的,就比如k==3时,arr[i]%3=2,j=1,这说明2加上了2再%3等于1,所以为了让数组不越界并且找到和arr[i]%k相加的那个数,我们把j-arr[i]%k变成(k+j-arr[i]%k)%k,初始化时i为0时除j=0外都为-1,最后输出dp[n][0]。还有一个特殊情况,如果没有任何数相加%k为0则j等于0就一直是0,但是我们要输出-1,所以最后我们要判断如果dp[n][0]为0,则输出-1。

代码

import java.util.Scanner;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class Main {
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int k = in.nextInt();
        long[] arr = new long[n + 1];
        for (int i = 1; i <= n; i++) {
            arr[i] = in.nextLong();
        }
        //设dp[i][j]表示前i个数中%k为j的最大和
        //取第i个数时dp[i][j]=dp[i-1][j-arr[i]%k]+arr[i]
        //不取第i个数时dp[i][j]=dp[i-1][j]
        //如果j-arr[i]%k<0那就让它等于(k+j-arr[i]%k)%k
        //所以取第i个数时dp[i][j]=dp[i-1][(k+j-arr[i]%k)%k]+arr[i]
        //初始化i为0时除j=0外都为-1
        long[][] dp = new long[n + 1][k];
        for (int i = 1; i < k; i++) {
            dp[0][i] = -1;
        }
        for (int i = 1; i <= n; i++) {
            for (int j = 0; j < k; j++) {
                if (dp[i - 1][(int)((k + j - arr[i] % k) % k)] != -1) {
                    dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][(int)((k + j - arr[i] % k) % k)] + arr[i]);
                } else {
                    dp[i][j] = dp[i - 1][j];
                }
            }
        }
        //如果到最后%k等于0的位置还为0,那么就说明从头到尾没有数相加能被
        //k整除,那么就输出1
        System.out.print(dp[n][0]==0?-1:dp[n][0]);
    }
}

2.DP16 合唱队形

题目

 解析

用最长上升子序列,以第i个为中心即可,d[i]表示从1到i的最大子序列,p[i]表示从n到i的最大子序列,d[i]=(d[0]到d[i-1]中小于这个数的最大值)+1,p[i]=(p[n]到p[i+1]中小于这个数的最大值)+1,每个数都要和1比,因为自身也有长度。

还有一种解法就是使用我在之前最长上升子序列(二)中运用的方法,贪心+二分查找。这个之前学过,可以去前面看。算是一种时间优化。

代码

解法一:
public class demo2 {//合唱队形
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] arr = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            arr[i] = in.nextInt();
        }
        //用最长上升子序列,以第i个为中心即可
        //d[i]表示从1到i的最大子序列
        //p[i]表示从n到i的最大子序列
        //d[i]=(d[0]到d[i-1]中小于这个数的最大值)+1
        //p[i]=(p[n]到p[i+1]中小于这个数的最大值)+1
        //初始化d[0],p[0]=0;
        //每个数都要和1比,因为自身也有长度
        int[] d=new int[n+1];
        int[] p=new int[n+1];
        for (int i = 1; i <= n; i++) {
            d[i] = 1;
            for (int j = 0; j < i; j++) {
                if (arr[j] < arr[i]) {
                    d[i] = Math.max(d[i], d[j] + 1);
                }
            }
        }
        for (int i = n; i >= 1; i--) {
            p[i] = 1;
            for (int j = n; j >i; j--) {
                if (arr[j] < arr[i]) {
                    p[i] = Math.max(p[i], p[j] + 1);
                }
            }
        }
        int min=0x3f3f3f3f;
        for(int i=1;i<=n;i++) {
            min=Math.min(min,n-(d[i]+p[i]-1));
        }
        System.out.print(min);
    }
}
 解法二:
/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 99715
 * Date: 2024-06-01
 * Time: 19:19
 */
import java.util.*;

// 注意类名必须为 Main, 不要有任何 package xxx 信息
public class demo3 {//合唱队形(时间优化)
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int[] arr = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            arr[i] = in.nextInt();
        }
        //时间优化
        int[] d = new int[n + 1];
        int[] p = new int[n + 1];
        int[] d1 = new int[n + 1];
        int pos = 0;
        for (int i = 1; i <= n; i++) {
            if (pos == 0 || arr[i] > d1[pos]) {
                d1[++pos] = arr[i];
            } else {
                int left = 1, right = pos;
                while (left < right) {
                    int mid = (left + right) / 2;
                    if (arr[i] > d1[mid]) {
                        left = mid + 1;
                    } else {
                        right = mid;
                    }
                }
                d1[right] = arr[i];
            }
            d[i] = pos;
        }
        int pos2=0;
        int[] p1=new int[n+1];
        for (int i = n; i >= 1; i--) {
            if (pos2 == 0 || arr[i] > p1[pos2]) {
                p1[++pos2] = arr[i];
            } else {
                int left = 1, right = pos2;
                while (left < right) {
                    int mid = (left + right) / 2;
                    if (arr[i] > p1[mid]) {
                        left = mid + 1;
                    } else {
                        right = mid;
                    }
                }
                p1[right] = arr[i];
            }
            p[i] = pos2;
        }
        int min = 0x3f3f3f3f;
        for (int i = 1; i <= n; i++) {
            min = Math.min(min, n - (d[i] + p[i] - 1));
        }
        System.out.print(min);
    }
}

3.小红的子串

题目

解析

这一题的主要思想是滑动窗口,捎带着些前缀和。因为要判断种类在l到r之间的子串数,而这无法直接计算,所以我们使用1到r减去1到l-1来计算。那么我们怎么计算1到x种类之间的字串数呢?我们可以在每次进窗口的时候让ret加上这个数添加的子串个数。子串个数可以用r-l+1表示。如图:

代码

/**
 * Created with IntelliJ IDEA.
 * Description:
 * User: 99715
 * Date: 2024-06-01
 * Time: 20:00
 */
import java.util.*;
public class demo4 {//小红的字串
    static char[] arr;
    static int n;
    public static void main(String[] args) {
        Scanner in=new Scanner(System.in);
        n=in.nextInt();
        int l=in.nextInt();
        int r=in.nextInt();
        arr=in.next().toCharArray();
        long ret=find(r)-find(l-1);
        System.out.print(ret);
    }
    static long find(int len) {
        int l=0,r=0,count=0;long ret=0;
        int[] hash=new int[26];
        while(r<n) {
            //进窗口
            if(hash[arr[r]-'a']++==0) count++;
            //判断合法以及使其合法
            while(count>len) {
                if(--hash[arr[l]-'a']==0) count--;
                l++;
            }
            ret+=r-l+1;
            r++;
        }
        return ret;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1801108.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

FENDI CLUB精酿啤酒品鉴体验

当提及“品质卓越&#xff0c;口感非凡”的啤酒时&#xff0c;FENDI CLUB精酿啤酒无疑是一个值得一试的选择。这款啤酒以其独特的酿造工艺和优质的原料&#xff0c;为消费者带来了与众不同的味觉享受。 一、独特的酿造工艺 FENDI CLUB精酿啤酒在酿造过程中&#xff0c;严格遵循…

关于 spring boot 的 目录详解 和 配置文件 以及 日志

目录 配置文件 spring boot 的配置文件有两种格式&#xff0c;分别是 properties 和 yml&#xff08;yaml&#xff09;。这两种格式的配置文件是可以同时存在的&#xff0c;此时会以 properties 的文件为主&#xff0c;但一般都是使用同一种格式的。 格式 properties 语法格…

使用 Django 创建 App

文章目录 步骤 1&#xff1a;创建 Django 项目步骤 2&#xff1a;创建 App步骤 3&#xff1a;配置 App步骤 4&#xff1a;编写代码步骤 5&#xff1a;运行服务器 在 Django 中&#xff0c;App 是组织代码的基本单元&#xff0c;它可以包含模型、视图、模板等组件&#xff0c;帮…

Hadoop的Windows环境准备

一、将Hadoop传输到Windows中 1、备份副本 cp -r /opt/softs/hadoop3.1.3/ /opt/softs/hadoop3.1.3_temp 2、删除备份的share目录 cd /opt/softs/hadoop3.1.3_temp rm -rf share/ 3、下载到Windows中 重命名去掉_temp 4、删除备份文件 rm -rf /opt/softs/hadoop3.1.3_t…

Redis到底支不支持事务?

文章目录 一、概述二、使用1、正常执行&#xff1a;2、主动放弃事务3、全部回滚:4、部分支持事务:5、WATCH: 三、事务三阶段四、小结 redis是支持事务的&#xff0c;但是它与传统的关系型数据库中的事务是有所不同的 一、概述 概念: 可以一次执行多个命令&#xff0c;本质是一…

如何提高网站排名?

提高网站排名是一个复杂的过程&#xff0c;涉及到多个方面的优化&#xff0c;包括但不限于内容质量、网站结构、用户体验、外部链接建设等&#xff0c;GSR这个系统&#xff0c;它是一种快速提升关键词排名的方案&#xff0c;不过它有个前提&#xff0c;就是你的站点在目标关键词…

自制植物大战僵尸:HTML5与JavaScript实现的简单游戏

引言 在本文中&#xff0c;我们将一起探索如何使用HTML5和JavaScript来创建一个简单的植物大战僵尸游戏。这不仅是一项有趣的编程挑战&#xff0c;也是学习游戏开发基础的绝佳机会。 什么是植物大战僵尸&#xff1f; 植物大战僵尸是一款流行的策略塔防游戏&#xff0c;玩家需…

C# MemoryCache 缓存应用

摘要 缓存是一种非常常见的性能优化技术&#xff0c;在开发过程中经常会用到。.NET提供了内置的内存缓存类 MemoryCache&#xff0c;它可以很方便地存储数据并在后续的请求中快速读取&#xff0c;从而提高应用程序的响应速度。 正文 通过使用 Microsoft.Extensions.Caching.Me…

Sql-labs的第一关

前言 我们在使用Sql-libs靶场进行Sql注入实验的时候&#xff0c;前提要求我们对mysql数据库结构要有一个大概的了解&#xff0c;因为mysql5.0以上的版本都会自带一个名为information_schema的数据库&#xff0c;这个数据库下面会有columns和tables两个表。 tables这个表的table…

【学习笔记】Windows GDI绘图(十一)Graphics详解(下)

文章目录 Graphics的方法Graphics.FromImageSetClip设置裁切区域IntersectClip更新为相交裁切区域TranslateClip平移裁切区域IsVisible判断点或矩形是否在裁切区域内MeasureCharacterRanges测量字符区域MeasureString测量文本大小MultiplyTransform矩阵变换 Graphics的方法 Gr…

【纯血鸿蒙】——响应式布局如何实现?

前面介绍了自适应布局&#xff0c;但是将窗口尺寸变化较大时&#xff0c;仅仅依靠自适应布局可能出现图片异常放大或页面内容稀疏、留白过多等问题。此时就需要借助响应式布局能力调整页面结构。 响应式布局 响应式布局是指页面内的元素可以根据特定的特征&#xff08;如窗口…

AI降重技术:革新论文查重与修改策略

AIGC降重指南&#xff1a;如何有效使用AI工具降低论文查重率&#xff1f; 论文查重和降重是确保学术成果原创性及学术诚信的关键步骤&#xff0c;直接影响我们的学业成果和毕业资格。传统的论文查重方法主要包括使用查重软件和个人自查&#xff0c;而论文降重通常涉及改写、使…

Docker中搭建likeadmin

一、使用Docker中的docker-compose搭建likeadmin 1.去网址&#xff1a;https://gitee.com/likeadmin/likeadmin_php中下载likeadmin 注册一个giee账号后 点那个克隆下载 按照序号在终端复制粘贴进去。 接着&#xff0c;输入ls 可以发现有一个这个&#xff1a; 里面有一个like…

数据结构复习指导之外部排序

目录 外部排序 复习提示 1.外部排序的基本概念 2.外部排序的方法 2.1对大文件排序时使用的排序算法&#xff08;2016&#xff09; 3.多路平衡归并与败者树 4.置换-选择排序&#xff08;生成初始归并段&#xff09; 4.1置换-选择排序生成初始归并段的实例(2023) 5.最佳…

单链表复习 (C语言版)

目录 一.顺序表与链表的区别 二.链表概念 三.单链表 1.单链表的开始与初始化 2.单链表的打印 3.单链表的尾插 重难点&#xff1a;单链表实现时的指针详解 4.单链表的头插 5.单链表的尾删 6.单链表的头删 小结&#xff1a; 7.单链表的查找 8.在指定位置前插入数据 …

深度学习的舌象诊断:从舌头上了解系统性疾病!

首先 深度学习算法能否解决东方医学中依靠医生经验的诊断问题&#xff1f;而要实现这个目标&#xff0c;需要什么呢&#xff1f; 用舌头诊断被称为口腔健康的指标&#xff0c;但在东方医学中&#xff0c;舌头也被用来评估全身的状况。换句话说&#xff0c;通过分析舌头的图像…

人工智能的统治:会是人类的终结吗?

使用ChatGPT运行/请求一系列提示以探索完全人工智能(AI)控制关键基础设施、自动化工厂 ( Tesla )、社交媒体 ( Meta )、SCADA和其他常见用途 (ModBUS?) 可能产生的后果后&#xff0c;我们进行了分析…… 以下是我们的考虑&#xff1a; 数据、提示和响应应被视为说明性的&…

通过影刀RPA,创建定时任务,自动获取图片验证码登录平台;

1.下载下载影刀客户端-影刀RPA - 影刀官网 2.安装&#xff0c;登录 3.应用创建->PC自动化应用 4.按照流程-创建【可双击或拖动】 5.保存 6.右击【创建的应用】->发版 7.选择触发器->【定时触发器】 根据提示配置 8.完成&#xff0c;每天平台会自动打开&#xff1b;…

算法学习笔记(7.7)-贪心算法(Dijkstra算法-最短路径问题)

目录 1.最短路径问题 2.Dijkstra算法介绍 3.Dijkstra算法演示 4.Dijkstra算法的代码示例 1.最短路径问题 图论中的一个经典问题&#xff0c;通常是指在一个加权图中找到从一个起始顶点到目标顶点的最短路径。 单源最短路径问题&#xff1a;给定一个加权图和一个起始顶点&…

http协议,tomcat的作用

HTTP 概念:Hyper Text Transfer Protocol&#xff0c;超文本传输协议&#xff0c;规定了浏览器和服务器之间数据传输的规则。 特点: 1.基于TCP协议:面向连接&#xff0c;安全 2. 基于请求-响应模型的:一次请求对应一次响应 3HTTP协议是无状态的协议:对于事务处理没有记忆能…