可恶的剪绳子问题

news2024/9/22 19:43:45

1. 剑指 Offer 14- I. 剪绳子

题目描述:给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m-1] 。请问 k[0]k[1]…*k[m-1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。

1.1 方法一:动态规划

1.1.1 推导

  • 求最大值问题可考虑使用动态规划算法解决;
  • 动态规划解题的四大要素:状态定义、状态转移方程定义、初始状态以及返回结果;
  • 针对剪绳子问题,目的是将一个长度为n的绳子划分为m段,m段绳子最大乘积是多少,其中m>1,也就是将绳子需至少划分为两段;
  • 动态规划四要素:
    1)状态F(i):长度为i的绳子,划分后最大乘积为F(i);
    2)状态转移方程:F(i)=Max{F(i),F(i-j)*j,(i-j)*j};
    3)初始状态:F(2)=1,长度为2的绳子至少划分为两段,因此每段长度为1;
    4)返回结果:F(n),长度为n的绳子划分后的最大乘积;
  • 长度为n的绳子划分后最大乘积,可由长度小于n的绳子的划分最大乘积进一步得到。假设将绳子划分为两段,一段长度为j,另一段长度为n-j,长度为n-j的绳子可以进一步划分,也可以不划分,因此有对应两种情况:
    1)n-j的绳子不再划分,则划分乘积为j*(n-j);
    2)n-j的绳子继续划分,则划分乘积为j*F(n-j);

1.1.2 代码实现

class Solution {
    // 动态规划
    // 状态F(i):长度为i的绳子,划分后最大乘积为F(i)
    // 状态转移方程:F(i)=Max{F(i),F(i-j)*j,(i-j)*j}
    // 初始状态:F(2)=1
    public int cuttingRope(int n) {
        int[] maxPro=new int[n+1];
        // 初始状态
        maxPro[2]=1;
        // 状态转移
        for(int i=3;i<=n;i++){
            for(int j=1;j<i;j++){
                maxPro[i]=Math.max(maxPro[i],j*maxPro[i-j]);
                maxPro[i]=Math.max(maxPro[i],(i-j)*j);
            }
        }
        // 返回结果
        return maxPro[n];
    }
}

1.2 方法二:数学规律

1.2.1 数学推导

  • 针对剪绳子问题,目的是将一个长度为n的绳子划分为a段,a段绳子最大乘积是多少,其中a>1,也就是将绳子需至少划分为两段;

  • 假设将绳子划分为a段,分别为n1,n2,…,na,由下列算术几何均值不等式可知,当n1=n2=…=na时,n1,n2,…,na乘积最大;
    在这里插入图片描述

  • 由上述公式可知当将长度为n的绳子等长划分后,乘积最大。假设每段绳子长度为x,共划分为a段,则乘积为xa,a=n/x,进一步推导:
    在这里插入图片描述
    也就是当x1/x最大时,划分乘积最大,令y=x1/x,进行隐函数求导可得:
    在这里插入图片描述
    但我们知道绳子划分段长度需要为整数,则可取近似值x=3或x=2,分别将x代入y=x1/x可知当x=3时划分乘积最大

  • 有上述推导可总结划分原则:
    1)尽可能将绳子划分为长度为3的段,共t段,剩余绳子长度有0,1,2三种可能;
    2)如果剩余绳子长度为0,说明绳子原长度正好为3的倍数,此时得到最优解3t
    3)如果剩余绳子长度为2,则将剩余部分看做整体,不再进一步划分,则划分乘积为3t*2;
    4)如果剩余绳子长度为1,则将长度为3的子段取出一个与剩余部分总长度为4(将其划分为两段长度为2的子段,因为此时2*2>1*3),则划分乘积为3t-1*2*2;

参考https://leetcode.cn/problems/jian-sheng-zi-ii-lcof/solution/mian-shi-ti-14-ii-jian-sheng-zi-iitan-xin-er-fen-f/

1.2.2 代码实现

class Solution {
    // 数学推导:将绳子尽可能按照长度为3的段分割,乘积最大
    public int cuttingRope(int n) {
        if(n<=2){
            return 1;
        }
        // 特殊情况
        if(n==3){
            return 2;
        }
        int res=n/3;  // 按照3分割,最多得到多少段
        int mod=n%3;  // 只有0,1,2三种情况
        if(mod==0){
            return (int)Math.pow(3,res);  // 说明是3的倍数
        }else if(mod==1){
            return (int)Math.pow(3,res-1)*4; // 3a+1,把最后两段3+1划分为2+2
        }else{
            return (int)Math.pow(3,res)*2; // 3a+2
        }
    }
}

2. 剑指 Offer 14- II. 剪绳子 II

题目描述:给你一根长度为 n 的绳子,请把绳子剪成整数长度的 m 段(m、n都是整数,n>1并且m>1),每段绳子的长度记为 k[0],k[1]…k[m - 1] 。请问 k[0]k[1]…*k[m - 1] 可能的最大乘积是多少?例如,当绳子的长度是8时,我们把它剪成长度分别为2、3、3的三段,此时得到的最大乘积是18。
答案需要取模 1e9+7(1000000007),如计算初始结果为:1000000008,请返回 1。

2.1 推导

  • 基础推导如1.2.1节所示;
  • 此处与上一道题不同的是,n的取值范围变大,因此在求3t时可能会发生边界值溢出的情况;
  • 基于取余运算如下图所示的性质,可通过循环取余的方法解决取值范围溢出的问题;
    在这里插入图片描述

2.2 代码实现

class Solution {
    public int cuttingRope(int n) {
        if(n<=2){
            return 1;
        }
        if(n==3){
            return 2;
        }
        int base=1000000007;
        int res=n/3;
        int mod=n%3;
        if(mod==1){
            res-=1;
        }
        // 计算pow(3,res)
        long target=1;
        while(res-->0){
            target=((target%base)*3)%base;
        }
        if(mod==0){
            return (int)(target%base); 
        }else if(mod==1){
            return (int)((target*4)%base);
        }else{
            return (int)((target*2)%base);
        }
    }
}

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

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

相关文章

3.6.共享内存的学习

目录 前言1. 共享内存2. shared memory案例3. 补充知识总结 前言 杜老师推出的 tensorRT从零起步高性能部署 课程&#xff0c;之前有看过一遍&#xff0c;但是没有做笔记&#xff0c;很多东西也忘了。这次重新撸一遍&#xff0c;顺便记记笔记。 本次课程学习精简 CUDA 教程-共享…

基于Qt5 实现的简易慕课爬取程序

基于Qt5 实现的简易慕课爬取程序 一、项目概述二、源代码 一、项目概述 名称&#xff1a;MookScrapy 这个项目主要是使用了 Qt 里面的 QNetworkAccessManager 去下载慕课网站的数据 https://coding.imooc.com&#xff0c;也就是这个网站里面的卡片信息。然后做一定的分析和展示…

【架构设计】酒店预订应用的系统设计架构(如 Airbnb、OYO)

Airbnb、Booking.com 和 OYO 等酒店预订应用程序如何提供从酒店列表到预订再到付款的流畅流程&#xff1f;而且都没有一个小故障&#xff01;在此博客中&#xff0c;您将获得对此的详细解释。由于它们非常庞大&#xff0c;以至于它们需要处理大量的用户流量。所以要管理这些&am…

计算机视觉:卷积核的参数可以通过反向传播学习到吗?

本文重点 在深度学习中,卷积神经网络(Convolutional Neural Networks, CNN)是一种常用的神经网络结构,其中卷积核是CNN的核心组件之一。卷积核是一个小矩阵,用于对输入数据进行卷积操作。卷积操作可以提取输入数据的特征,通过不同的卷积核可以提取不同的特征。 在前面课…

Wireshark TS | 二谈访问网页失败

前言 又一个访问网页失败的案例&#xff0c;该案例来自于 Wireshark sharkfest 2018 - Point And ShootPacket&#xff0c;其中的 Case 2 Cannot see homepage&#xff0c;描述的是来自 OSAKA 的用户抱怨访问一些网站页面不能显示&#xff0c;但是另外一些网站页面可以&#x…

软件测试岗位新标准:ISTQB认证与软件测试工程师职业发展

随着信息技术的飞速发展&#xff0c;软件测试行业也变得越来越重要。软件测试是保证软件质量的关键环节&#xff0c;因此&#xff0c;软件测试工程师的岗位也越来越受到重视。 ISTQB认证成为了衡量软件测试工程师职业能力的标准。 下面领测国际ISTQB考试认证中心就带您了解一下…

depot_tools问题记录 - 执行fetch/gclient命令无响应

文章目录 前言开发环境问题描述问题分析解决方案最后 前言 在研究将Dart dill文件序列化为可读文本时遇到的问题。 开发环境 macOS: 13.4 问题描述 之前使用depot_tools中的fetch/gclient命令还是正常的&#xff0c;今天想实测--no-history参数时突然遇到命令无响应的情况…

Redis 删除 key用 del 和 unlink 有啥区别?

问题 del 和 unlink 有啥区别啊&#xff1f;为什么String类型删除不会做异步删除&#xff1f; 彬彬回答 DEL 和 UNLINK 都是同步的释放 key 对象&#xff0c;区别是怎么释放后面的 value 对象 DEL 每次都是同步释放 value 部分&#xff0c;如果 value 很大&#xff0c;例如一…

Openssh升级方法详解

项目组linux服务器被绿盟扫描出openssh 1.0.2版本有漏洞&#xff0c;需要升级到7.5版本&#xff0c;以下是升级过程&#xff1a; 第一步 安装Telnet服务 先下Openssh软件包 看你需要什么版本http://ftp.openbsd.org/pub/OpenBSD/OpenSSH/portable/ 1.查看当前的ssh服务版本 …

【前端】网页开发精讲与实战 HTML Day 2

&#x1f680;Write In Front&#x1f680; &#x1f4dd;个人主页&#xff1a;令夏二十三 &#x1f381;欢迎各位→点赞&#x1f44d; 收藏⭐️ 留言&#x1f4dd; &#x1f4e3;系列专栏&#xff1a;前端 &#x1f4ac;总结&#xff1a;希望你看完之后&#xff0c;能对你有…

看完这篇 教你玩转渗透测试靶机Vulnhub——The Planets:Mercury

Vulnhub靶机The Planets:Mercury渗透测试详解 Vulnhub靶机介绍&#xff1a;Vulnhub靶机下载&#xff1a;Vulnhub靶机安装&#xff1a;Vulnhub靶机漏洞详解&#xff1a;①&#xff1a;信息收集&#xff1a;②&#xff1a;漏洞发现&#xff1a;③&#xff1a;SSH登入&#xff1a;…

架构师进阶之路 - 微服务怎么划分

目录 微服务划分目标 业务、技术、团队导向规划服务 领域检查 依赖DAG检查 分布式事务检查 性能分布检查 稳定&#xff08;易变&#xff09;性检查 调用链检查 微服务划分目标 我们常说服务的合理划分是微服务成功的重中之重&#xff0c;一个合理的服务划分应该符合一下…

SQL中如何用快照,恢复被误删的数据?

什么是快照 数据库快照是sql server 2005的一个新功能。MSDN上对它的定义是&#xff1a; 数据库快照是数据库&#xff08;称为“源数据库”&#xff09;的只读静态视图。在创建时&#xff0c;每个数据库快照在事务上都与源数据库一致。在创建数据库快照时&#xff0c;源数据库…

THREE.JS镜头随鼠标晃动效果

为了让动画更灵活并且简单 借助gsap让其具有更多可能&#xff0c;在未来更容易扩充其他动效 gsap Dom跟随鼠标移动 gsap.quickTo() 首先要监听鼠标移动&#xff0c;并且将移动的值转换到 -1 和 1 之间 方便处理 private mousemove(e: MouseEvent) {const x (e.clientX / inner…

spring10-配置数据元

他的作用是提高我们程序性能的&#xff1a;我们怎么用呢&#xff01;先创建我们数据源对象&#xff1a;创建初始化对象之后&#xff0c;创建数据源对象之后&#xff0c;会给我们一些初始化资源。 使用完后还给他 &#xff0c;这是一种环保的思想。 常见的数据源&#xff1a;底…

干货-卷起来,企业级web自动化测试实战落地(二)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 WebDriver的基本使…

毫米波雷达 TI IWR1443 测试官方程序(Out Of Box Demo)

IWR1443 windows 文章目录 1、准备工作1.1、mmWave SDK1.2、Code Composer Studio&#xff08;CCS&#xff09;1.3、Uniflash1.4、TI Cloud Agent 2、导入工程3、烧录3.1、先将 IWR1443 调到 Flashing Mode3.2、使用 UniFlash 软件 4、运行GUI4.1、IWR1443 调到 Functional Mo…

【计算机组成与体系结构Ⅰ】实验0 Logisim 入门实验

一、实验目的 1&#xff1a;掌握加减法器工作原理。 2&#xff1a;能够设计出一个n位加减法器。 3&#xff1a;熟悉Logisim软件使用。 二、实验环境 &#xff08;1&#xff09;Logisim 2.7.1 &#xff08;2&#xff09;Microsoft Windows 10 三、实验内容 1&#xff1a;设…

FastAPI中如何正确理解和使用:async和await

1 缘起 项目需要, 技术选型使用FastAPI。 开发过程中,遇到需要异步操作的场景, 查阅相关FastAPI异步信息的过程中,发现了async和await组合技, 通过阅读官方文档和实际测试,发现,async和await并不是传统意义上的异步(如线程池异步执行任务), async和await的融合技是应…

SEGA: Semantic Guided Attention on Visual Prototype for Few-Shot Learning

方法比较简单&#xff0c;利用语义改进prototype&#xff0c;能促进性提升