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


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;
    }
}

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

锐捷校园网自助服务-字符过滤存在缺陷

锐捷校园网自助服务-字符过滤存在缺陷 漏洞介绍 令人感到十分遗憾的是&#xff0c;锐捷网络安全应急响应中心对漏洞上报似乎缺少了一些奖励&#xff0c;令人对官方上报漏洞失去了些许兴趣​。 该缺陷仅仅打破了安全检查防护&#xff0c;并没有造成实质性危害&#xff0c;至于…

16.Redis之Redis事务

1.MySQL 事务 原子性: 把多个操作,打包成一个整体了 一致性: 事务执行之前,和之后,数据都不能离谱~ 持久性: 事务中做出的修改都会存硬盘 隔离性: 事务并发执行,涉及到的一些问题~~ 2.Redis事务 2.1 认识Redis事务 • 弱化的原⼦性: redis 没有 "回滚机制". …

本地知识库开源框架Fastgpt、MaxKB产品体验

本地知识库开源框架Fastgpt、MaxKB产品体验 背景fastgpt简介知识库共享部署 MaxKB总结 背景 上一篇体验了Quivr、QAnything两个开源知识库模型框架&#xff0c;这次介绍两款小众但是体验比较好的产品。 fastgpt 简介 FastGPT 是一个基于 LLM 大语言模型的知识库问答系统&am…

8-Django项目--登录及权限

目录 templates/login/login.html templates/login/404.html views/login.py utils/pwd_data.py auth.py settings.py 登录及权限 登录 views.py 中间件 auth.py templates/login/login.html {% load static %} <!DOCTYPE html> <html lang"en"&g…

掘金AI 商战 宝典 初级班:如何用AI做文案(实战实操 现学现用 玩赚超值)

未来会用AIE剑客将干掉99.99%不会AI的人! 课程目录&#xff1a; 10-第十讲用AI面试 11-第十一讲用AI写演讲稿 12-第十二讲用AI写工作总结 13-第十三讲用AI写日报周报 14-第十四讲用AI拟定各类合同 15-第十五讲用AI写课程教案 16-第十六讲用AI做商业分析 17-第十七讲用…

20 - grace数据处理 - 地下水储量计算过程分解 - 地下水储量计算

20 - grace数据处理 - 地下水储量计算过程分解 - 地下水储量计算 0 引言1 地下水储量变化计算过程0 引言 由水平衡方程可以将地下水储量的计算过程分解为3个部分,第一部分计算陆地水储量变化、第二部分计算地表水储量变化、第三部分计算冰后回弹改正、第四部分计算地下水储量变…

Kotlin使用Dagger2但无法生成对应类 Unresolved reference: DaggerMyComponent

最近在使用Dagger2时&#xff0c;遇到这个错误&#xff0c;app/build/generated/source/没有生成对应类&#xff0c;没有生成如下类&#xff0c;网上看了许多博客替换版本&#xff0c;添加dagger2的其他依赖均未成功&#xff0c;最终看到一篇大佬的文章才终于得以解决 解决&am…

electron打包时资源下载失败cannot resolve xxx/30.0.9/electron-v30.0.9-win32-ia32.zip

同学们可以私信我加入学习群&#xff01; 正文开始 问题描述解决方案总结 问题描述 最近electron更新频繁&#xff0c;而我在用electron做个人项目&#xff0c;对稳定性没有太高要求&#xff0c;希望保持着electron的最新版本&#xff0c;所以就没有固定版本。 单位网络不太好…

Java(八)——String类

文章目录 String类String的构造及内存分布构造内存分布 常用方法判等比较查找转化替换拆分截取 字符串的不可变性StringBuilder和StringBuffer String类 C语言中没有专门的字符串类型&#xff0c;一般使用字符数组或字符指针表示字符串&#xff0c;而字符串的函数需要包含头文…

【数据结构】二叉树:简约和复杂的交织之美

专栏引入&#xff1a; 哈喽大家好&#xff0c;我是野生的编程萌新&#xff0c;首先感谢大家的观看。数据结构的学习者大多有这样的想法&#xff1a;数据结构很重要&#xff0c;一定要学好&#xff0c;但数据结构比较抽象&#xff0c;有些算法理解起来很困难&#xff0c;学的很累…

PWN-栈迁移

栈迁移 题目&#xff1a;BUUCTF在线评测 (buuoj.cn) 知识点&#xff1a;栈迁移 使用情况&#xff1a;题目中有栈溢出&#xff0c;但是 栈溢出的范围 有限&#xff0c;导致构造的ROP链不能完全写入到栈中&#xff0c;此时需要进行栈迁移&#xff0c;将栈迁移到能接受更多数据的…

GD32F系列MCU片上Flash中Code区和Data区使用解密

GD32F系列MCU产品片上Flash分Code区和Data区&#xff0c;以GD32F303系列为例&#xff0c;从GD32F303xx Datasheet中可以获取code区和data区大小&#xff0c;那Code区和Data区在代码执行上有什么差别呢&#xff1f; Code区代码运行0等待&#xff0c;一般用于存放实时性要求高的代…

STM32(八):独立看门狗 (标准库函数)

前言 上一篇文章介绍了STM32单片机中的USART串口通信&#xff0c;这篇文章我们来介绍一下如何用STM32单片机中的独立看门狗来实现检测按键点灯的程序。 一、实验原理 单片机系统会由于受到外界的干扰&#xff0c;而造成程序执行紊乱&#xff0c;系统无法正常运行。为了防止这…

混合模型方差分析

文章目录 一、说明二、受试者“间”因素和受试者“内”因素的意思&#xff1f;三、混合模型方差分析回答 3 件事四、混合模型方差分析的假设 一、说明 在本文中&#xff0c;我将讨论一种称为混合模型方差分析的方差分析变体&#xff0c;也称为具有重复测量的 2 因素方差分析。…

python替换占位符为变量,实现读取配置文件

文章目录 背景1、定义正则表达式2、替换变量占位符3、实现功能 背景 使用python编写小工具&#xff0c;有一个配置文件&#xff0c;希望实现类似shell命令的&#xff0c;定义变量并且使用${}或者$来引用。如果有好的建议欢迎讨论。 配置文件示例内容如下: D:\project\test\pr…

word里面没有Acrobat选项

加载项被禁止&#xff0c;选择项里面&#xff0c;没有Acrobat选项 文件-》选项 加载项-》com加载项-》转到 添加Acrobat 出现Acrobat选项

阿里云部署nodejs

目录 1、安装node.js 1-1 进入opt/software 1-2 下载node.js安装包 1-3 解压 2 配置环境变量 2-1 vim中配置环境变量 2-2 命令行中保存环境变量 2-3 检查安装版本 2-3 更换镜像 3、上传node.js项目 1-1 启动项目 1-2 配置对应的安全组 ​编辑 4、pm2启动多个node项…

《PNAS》和《Nature Communications》仿章鱼和蜗牛的粘液真空吸附,赋予了机器人吸盘新的“超能力”

想象一下&#xff0c;如果机器人能够像章鱼一样牢牢吸附在粗糙崎岖的岩石上&#xff0c;或者像蜗牛那样在墙面上悠然负重爬行&#xff0c;那会是多么神奇的一幕&#xff01;近日&#xff0c;布里斯托大学机器人实验室的Jonathan Rossiter教授课题组就为我们带来了这样的“超能力…

Java_Mybatis

Mybatis是一款优秀的持久层框架&#xff0c;用户简化JDBC(使用Java语言操作关系型数据库的一套API)开发 使用Mybatis查询所有用户数据&#xff1a; 代码演示&#xff1a; UserMapper&#xff1a; Mapper //被调用时会通过动态代理自动创建实体类&#xff0c;并放入IOC容器中…

一文了解JVM面试篇(上)

Java内存区域 1、如何解释 Java 堆空间及 GC? 当通过 Java 命令启动 Java 进程的时候,会为它分配内存。内存的一部分用于创建 堆空间,当程序中创建对象的时候,就从对空间中分配内存。GC 是 JVM 内部的一 个进程,回收无效对象的内存用于将来的分配。 2、JVM 的主要组成…