算法——贪心法(Greedy)

贪心法

  • 把整个问题分解成多个步骤,在每个步骤都选取当前步骤的最优方案,直到所有步骤结束;在每一步都不考虑对后续步骤的影响,在后续步骤中也不再回头改变前面的选择。
  • 不足之处:
    • 贪心算法并不能保证获得全局最优解,但总能获得局部最优解
    • 贪心算法只能确定某些问题的可行性范围

  • 贪心算法可解决的问题通常大部分都有如下的特性:

    • 1、有一个以最优方式来解决的问题。为了构造问题的解决方案,有一个候选的对象的集合:比如不同面值的硬币

    • 2、随着算法的进行,将积累起其他两个集合:一个包含已经被考虑过并被选出的候选对象,另一个包含已经被考虑过但被丢弃的候选对象

    • 3、有一个函数来检查一个候选对象的集合是否提供了问题的解答。该函数不考虑此时的解决方法是否最优

    • 4、还有一个函数检查是否一个候选对象的集合是可行的,即是否可能往该集合上添加更多的候选对象以获得一个解。和上一个函数一样,此时不考虑解决方法的最优性

    • 5、选择函数可以指出哪一个剩余的候选对象最有希望构成问题的解 

    • 6、最后,目标函数给出解的值 

  • 利用贪心法求解的问题应具备如下2个特征 

    • 1、贪心选择性质

      一个问题的整体最优解可通过一系列局部的最优解的选择达到,并且每次的选择可以依赖以前作出的选择,但不依赖于后面要作出的选择。

    • 2、最优子结构性质

      当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。

  • 与动态规划的区别

    贪心算法与动态规划的不同在于它对每个子问题的解决方案都做出选择,不能回退。动态规划则会保存以前的运算结果,并根据以前的结果对当前进行选择,有回退功能。

一、 正整数分解使得乘积最大问题(贪心)

问题描述:

设n是一个正整数。现在要求将n分解为若干个自然数之和,且使这些自然数的乘积最大。

分析:

  • 将这个大问题分解为两个小问题:

    • (1)这些自然数是互不相同的

    • (2)这些自然数可以是相同的

  • 1不会增大乘积,反而会占据和,所以分解出的数中不应有 1

  • 先找几个数作例子,找规律

  • 注意应用到实际问题时,可能存在两个问题:

    • 1、乘积出来的数太大,题目要求返回取余后的结果即可

      • 解决办法:一边乘积,一边取余,而非全部乘积完成后取余

    • 2、分解出来的数太多,把它们乘积到一起会超时

      • 解决办法:快速幂(不用递归)

    • 见下面的第二题

1、不同的自然数

将其分解成连续的整数,从2开始,2,3,4,……将剩余的数按照从后往前的次序一次均匀分配。

package no1_1;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        int n=input.nextInt();
        int k=2; // 从2开始分解成连续的数
        // 创建一个包含100个整数的数组
        int in[]=new int[100];
        int i=0;
        // 把n分成2,3,4,……一组连续的数字
        while(n>=k) {
            in[i++]=k;
            n-=k;
            k++;
        }
        // 如果有剩余的数,从后往前加到前面分好的一组连续数字中
        if(n!=0) {
            // 如果分剩的数与上一个减数相同,先对其加1,才能保证前面的减数都能均匀分配
            if(n==in[i-1]) {
                in[i-1]++;
                n--;
            }
            // 从后往前均匀分配
            for(int j=0;j<n;j++) {
                in[i-1-j]++;
            }
        }
        // 初始化乘积result为1
        int result=1;
        // 计算最大乘积
        for(int j=0;j<=i-1;j++) {
            result*=in[j];
        }
        System.out.println(result);
    }	
}

2、可以有相同的自然数

主要将 n 分解成2和3,主要是3。

package no1_1;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        int n=input.nextInt();
        // 创建一个包含100个整数的数组
        int in[]=new int[100];
        int i=0;
        // 当n不等于2和4时,按3进行分解
        while(n!=2 && n!=4) {
            in[i++]=3;
            n-=3;
        }
        // 当n不等于0时,按2继续分解
        while(n!=0) {
            in[i++]=2;
            n-=2;
        }
        // 初始化乘积result为1
        int result=1;
        // 计算最大乘积
        for(int j=0;j<=i-1;j++) {
            result*=in[j];
        }
        System.out.println(result);
    }	
   
}

二、数的潜能(贪心)

分析

  • 快速幂:快速幂 - OI Wiki (oi-wiki.org)
package no1_1;
import java.util.*;
public class Main {
    public static void main(String[] args) {

        Scanner input=new Scanner(System.in);
        long n=input.nextLong();
        if(n==1) {
        	System.out.println(1);
        }else {
            long threeNums=n/3;//n最多能分出多少个3
            int result=1;
            if(n%3==1) {//分解成threeNums个3和两个2,(4是特殊的例子,拆分成两个2时,乘积最大)
            	threeNums--;
            	result=4;
            }else if(n%3==2) {//分解成threeNums个3和一个2
            	result=2;
            }   
        	result=binpow(result,3,threeNums,5218);          
            System.out.println(result);
        }        
    }	
  //使用二进制快速幂算法计算 baseNumber 的 power 次幂对 modNumber 取模的结果
    public static int binpow(int result,int baseNumber,long power,int modNumber) {
    	result%=modNumber;// 对底数取模,防止溢出
    	baseNumber%=modNumber;// 对底数取模,防止溢出
    	while(power>0) {
    		if((power&1)==1) {
    			result=result*baseNumber%modNumber;// 如果 幂 的当前位为 1,则更新结果
    		}
    		baseNumber=baseNumber*baseNumber%modNumber;// 底数自乘取模,相当于2次幂后取模
    		power>>=1;//power  右移一位
    	}
    	return result;
    }
}


三、最大分解

分析

  • n=a0>a1>a2>……>ap,a(i+1)是a(i)的最大约数,
  • 比如10>5>1, 5是10不等于自身的最大约数,1是5不等于自身的最大约数
  • 找到每层不等于自身的最大约数即可
package no1_1;
import java.util.*;
public class Main {
    public static void main(String[] args) {
        Scanner input=new Scanner(System.in);
        int n=input.nextInt();
        long sum=0;
        while(n!=1) {//当n==1时,就不能再分解下去了
        	//当i==n时,n为质数,不等于它自身的最大约数即为1
        	for(int i=2;i<=n;i++) {
    			if(n%i==0) {
    				n=n/i;
    				sum+=n;
    				break;
    			}
    		}
        }
        System.out.println(sum);
    }
}

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

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

相关文章

用通俗易懂的方式讲解:内容讲解+代码案例,轻松掌握大模型应用框架 LangChain

本文介绍了 LangChain 框架&#xff0c;它能够将大型语言模型与其他计算或知识来源相结合&#xff0c;从而实现功能更加强大的应用。 接着&#xff0c;对LangChain的关键概念进行了详细说明&#xff0c;并基于该框架进行了一些案例尝试&#xff0c;旨在帮助读者更轻松地理解 L…

申请ZeroSSL泛域名域名证书 并部署阿里云测试

安装acme.sh 安装过程中可能会失败 多试几次就会成功 wget -O - https://raw.githubusercontent.com/acmesh-official/acme.sh/master/acme.sh | sh -s -- --install-online -m 你的邮箱gmail.com安装完成后重新加载 Bash&#xff1a; source ~/.bashrc然后也可以开启自动更…

若依基于sm-crypto实现前后端登录密码加密

上一节介绍了基于jsencrypt实现的密码加密解密登录功能&#xff0c;这次来介绍基于sm-crypto实现前后端登录密码加密&#xff0c;本次采用的是sm2进行的加密解密。 后端 首先从后端代码开始写起(因为公钥和私钥都是要从java代码中生成)&#xff1a; 首先需要引入sm-crypto的j…

ubantu运维,nginx相关操作

1、使用 命令ps aux | grep nginx查找nginx 运行目录&#xff0c;如下图&#xff1a; 2、使用 ​​​​​​​命令cd /usr/sbin 切换到nginx 运行目录&#xff0c;如下图&#xff1a; 3、修改配置文件后&#xff0c;使用 nginx -t 命令测试nginx配置文件的语法是否正确&#x…

RTMP 视频数据封装

RTMP 协议 与HTTP(超文本传输协议)同样是一个基于TCP的Real Time Messaging Protocol(实时消息传输协议)。由Adobe Systems公司为Flash播放器和服务器之间音频、视频和数据传输开发的一种开放协议 。在国内被广泛的应用于直 播领域。HTTP默认端口为80&#xff0c;RTMP则为1935…

Python 安卓开发:Kivy、BeeWare、Flet、Flutter

kivy&#xff1a;https://github.com/kivy python-for-android &#xff1a;https://python-for-android.readthedocs.io/en/latest/ BeeWare&#xff1a;https://docs.beeware.org/en/latest/ Flet&#xff1a;https://github.com/flet-dev/flet 把 PySide6 移植到安卓上去&a…

如何使用网络测试仪构造特殊流量

为什么要仿真特殊流量 在现网中&#xff0c;网络流量时常伴随着突发&#xff0c;突发流量可能会造成网络的拥塞&#xff0c;从而产生丢包、抖动和时延&#xff0c;导致网络服务质量整体下降。面对宏观上的突发&#xff0c;通常采用在网络设备入向限速或者流量整形功能来消除突…

kotlin运行

1.使用android studio 由于我本身是做android的&#xff0c;android studio本身有内置kotlin的插件。但若只是想跑kotlin的程序&#xff0c;并不像和android程序绑在一起&#xff0c;可以创建一个kt文件&#xff0c;在里面写一个main函数&#xff0c;就可以直接运行kotlin程序…

MySQL第二次

作业要求&#xff1a; 作业代码实现&#xff1a; create database db_04 default charsetutf8mb4;use db_04;create table if not exists t_hero(id int primary key auto_increment,name varchar(20) not null unique,nickname varchar(50) not null unique,address varchar…

Vue面试之v-if与v-show的区别

Vue面试之v-if与v-show的区别 DOM渲染初始渲染性能切换开销标签配合源码实现 最近在整理一些前端面试中经常被问到的问题&#xff0c;分为vue相关、react相关、js相关、react相关等等专题&#xff0c;可持续关注后续内容&#xff0c;会不断进行整理~ 作为Vue中两种条件性渲染元…

Python 最新版本 3.12.1 环境配置(windows)

文章目录 python 3.12.1环境安装3.12.1 网盘下载3.12.1 官网下载 python 安装完成测试第一个 python 程序Hello Python python 3.12.1环境安装 3.12.1 网盘下载 python 3.12.1 百度网盘地址&#xff1a;https://pan.baidu.com/s/1SAcH_uH0T3DiERn6AZeQlg?pwd4242 提取码&a…

跟着cherno手搓游戏引擎【4】窗口抽象、GLFW配置、窗口事件

引入GLFW&#xff1a; 在vendor里创建GLFW文件夹&#xff1a; 在github上下载&#xff0c;把包下载到GLFW包下。 GitHub - TheCherno/glfw: A multi-platform library for OpenGL, OpenGL ES, Vulkan, window and input修改SRC/premake5.lua的配置&#xff1a;12、13、15、36…

阿里云服务器ECS介绍_高性能云服务器_为了无法计算的价值

阿里云高性能云服务器60%单实例最大性能提升&#xff0c;35Gbps内网带宽&#xff0c;网络增强&通用型云服务器、本地SSD型云服务器、大数据型云服务器、GPU异构型云服务器&#xff0c;阿里云百科aliyunbaike.com分享阿里云高性能云服务器&#xff1a; 阿里云高性能云服务器…

修改权限控制(chmod命令、chown命令)

1.chmod命令 功能&#xff1a;修改文件、文件夹权限&#xff08;注意&#xff0c;只有文件、文件夹的所属用户或root用户可以修改&#xff09; 语法&#xff1a;chmod [-R] 权限 参数 权限&#xff0c;要设置的权限&#xff0c;比如755&#xff0c;表示&#xff1a;rwxr-xr-x…

Python入门-面向对象

1.类和对象 是不是很熟悉&#xff1f;和Java一样&#xff0c;在Python中&#xff0c;都可以把万物看成(封装成)对象。它俩都是面向对象编程 1.1 查看对象数据类型 a 10 b 9.8 c helloprint(type(a)) print(type(b)) print(type(c))运行结果&#xff1a; D:\Python_Home\v…

自定义数据实现SA3D

SA3D&#xff1a;Segment Anything in 3D with NeRFs 实现了3D目标分割 原理是利用SAM(segment anything) 模型和Nerf分割渲染3D目标&#xff0c; SAM只能分块&#xff0c;是没有语义标签的&#xff0c;如何做到语义连续&#xff1f; SA3D中用了self-prompt, 根据前一帧的mask…

基于Python的汽车信息爬取与可视化分析系统

介绍 这款汽车信息网站是基于多项技术和框架设计的全面的汽车信息展示及查询系统。其中&#xff0c;采用了Python Django框架和Scrapy爬虫技术实现数据的抓取和处理&#xff0c;结合MySQL数据库进行数据存储和管理&#xff0c;利用Vue3、Element-Plus、ECharts以及Pinia等前端…

MFC为资源对话框添加消息处理函数和初始化控件

现在我VC6新建了一个对话框工程&#xff1b;又在资源添加了一个新的对话框&#xff0c;并为新的对话框添加了名为CTestDlg的类&#xff1b; 在主对话框的cpp文件包含#include "TestDlg.h"&#xff1b; 在主对话框的cpp文件的OnInitDialog()成员函数中&#xff0c;添…

leetcode 2645. 构造有效字符串的最少插入数-python

题目&#xff1a; 给你一个字符串 word &#xff0c;你可以向其中任何位置插入 “a”、“b” 或 “c” 任意次&#xff0c;返回使 word 有效 需要插入的最少字母数。 如果字符串可以由 “abc” 串联多次得到&#xff0c;则认为该字符串 有效 。 解题方法 1.先判断字符串是否…

快速排序的背后——深入理解时间复杂度

时间复杂度的概念衡量算法性能的重要标准&#xff0c;是算法设计和性能优化中的关键概念&#xff0c;对于编写高效、稳定和可扩展的程序至关重要。但是&#xff0c;初学者对于如何理解和应用时间复杂度则显得较为困难&#xff0c;本文以快速排序为例进一步加深对时间复杂度的理…