贪心(总结+例题)_贪心算法路径规划-程序员宅基地

技术标签: 算法  C++  c++  贪心算法  

贪心是什么?

定义:

所谓贪心算法是指,在对问题求解时,总是做出在当前看来是最好的选择。 也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。

注意

贪心算法不是对所有问题都能得到整体最优解,关键是贪心策略的选择

算法思路

贪心算法一般按如下步骤进行:

  1. 建立数学模型来描述问题
  2. 把求解的问题分成若干个子问题
  3. 对每个子问题求解,得到子问题的局部最优解
  4. 把子问题的解局部最优解合成原来解问题的一个解

使用条件

  1. 贪心选择性质

一个问题的整体最优解可通过一系列局部的最优解的选择达到,并且每次的选择可以依赖以前作出的选择,但不依赖于后面要作出的选择。这就是贪心选择性质。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解

  1. 最优子结构性质

当一个问题的最优解包含其子问题的最优解时称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用贪心法求解的关键所在。在实际应用中,至于什么问题具有什么样的贪心选择性质是不确定的,需要具体问题具体分析

存在问题

  1. 不能保证解是最佳的。因为贪心算法总是从局部出发,并没从整体考虑
  2. 贪心算法一般用来解决求最大或最小解
  3. 贪心算法只能确定某些问题的可行性范围

例题

1
I love string 我爱弦乐

Problem Description

Mr X likes to play string games.
Mr X has an operation sequence. This operation sequence can be written
as a string. For each operation, the next character of the operation
sequence can be inserted before or after the current string. For
example, my operation sequence is “aabac”, suppose the sequence
obtained after the first four operations is “baaa”, then after the
last operation, the string may become “baaac” or “cbaaa”. It can be
seen that there is only one operation method for the first operation.
For other operations, there are only two methods of operation.

For each operation method, there will be a score. The smaller the
lexicographic order of the final string, the higher the final score.

Then, for a given operation sequence, how many operation methods can
get the maximum score.

The two operation methods are different. If and only if there is a
certain operation (not the first operation), one operation will be
inserted before the current string, and the other operation will be
inserted after the current string.

Input

Enter a positive integer T (T≤10) on the first line to represent the number of test cases.
For each test case:

the first line contains a integer n (1≤n≤100000) to represent the
length of the string.

the second line contains a string of lowercase letters , which
represents the sequence of operations.

Output

For each test case, output a line of a positive integer to represent
the number of schemes, and the answer is modulo 1000000007

Sample Input

1
5
abcde

Sample Output

1

思路:
字典序小的放后面,大的放前面~
相同就乘2

#include <iostream>
using namespace std;
const int N = 1e5 + 10, mod = 1e9 + 7;;

int main()
{
    
    int T;
    cin >> T;
    while (T--)
    {
    
        int n;
        string str;
        cin >> n >> str;
        
        long long ans = 1;
        char l = str[0], r = str[0];
        for (int i = 1; i < n; i++)
        {
    
            if (str[i] == l && str[i] == r) ans = ans * 2 % mod;
            else if (str[i] <= l) l = str[i];  
            else r = str[i];
        }
        
        cout << ans % mod << endl;
    }
    return 0;
}

2
区间选点 传送门

给定 N 个闭区间 [ai,bi],请你在数轴上选择尽量少的点,使得每个区间内至少包含一个选出的点。

输出选择的点的最小数量。

位于区间端点上的点也算作区间内。

输入格式

第一行包含整数 N,表示区间数。

接下来 N 行,每行包含两个整数 ai,bi,表示一个区间的两个端点。

输出格式

输出一个整数,表示所需的点的最小数量。

数据范围

1≤N≤105
−109≤ai≤bi≤109

输入样例:

3
-1 1
2 4
3 5

输出样例:

2

在这里插入图片描述
将每个区间按照右端点从小到大进行排序(贪心的常规操作)
从前往后枚举区间,end值初始化为无穷小

  • 如果本次区间不能覆盖掉上次区间的右端点, ed < range[i].l

    说明需要选择一个新的点, res ++ ; ed = range[i].r;

证明:

  1. 找到cnt个点,满足题意情况,则最优解Ans <= cnt
  2. 找到cnt个点,即找到cnt个区间,且区间从左到右依次排好,且没有相同的交集,则说明可能有区间没有被这cnt个点覆盖过,所以最优解Ans>= cnt ,则Ans == cnt

证毕。

#include <iostream>
#include <algorithm>

using namespace std;

const int N = 100010;

int n;
struct Range
{
    
    int l, r;
    bool operator< (const Range &W)const
    {
    
        return r < W.r;
    }
}range[N];

int main()
{
    
    scanf("%d", &n);
    
    for (int i = 0; i < n; i ++ ) 
        scanf("%d%d", &range[i].l, &range[i].r);

    sort(range, range + n);

    int res = 0, ed = -2e9;
    for (int i = 0; i < n; i ++ )
        if (range[i].l > ed)
        {
    
            res ++ ;
            ed = range[i].r;
        }

    printf("%d\n", res);

    return 0;
}

再来个娱乐题

货仓选址

在一条数轴上有 N 家商店,它们的坐标分别为 A1∼AN。

现在需要在数轴上建立一家货仓,每天清晨,从货仓到每家商店都要运送一车商品。

为了提高效率,求把货仓建在何处,可以使得货仓到每家商店的距离之和最小。

输入格式

第一行输入整数 N。

第二行 N 个整数 A1∼AN。

输出格式

输出一个整数,表示距离之和的最小值。

数据范围

1≤N≤100000, 0≤Ai≤40000

输入样例:

4 6 2 9 1

输出样例:

12

只要排序找中点即可
设仓库位置为k
答案为 ans = min{ | X1 - k | + | X2 - k | + | X3 - k |+…+ | Xn - k | }

证明:
这道题目中,每一个点到中位数的距离,都是满足全局的最有性,而不是局部最优性。
设在仓库建在 X 轴坐标处,X 左侧的商店有 P 家 ,右侧的商店有 Q 家
若 P < Q ,则每把仓库的选址向右移动 1 单位距离,距离之和就会变小 Q - P。
同理,若 P > Q , 则仓库的选址向左移动 1 单位距离,距离之和就会变小。
P = Q 时为最优解。

#include <iostream>
#include <algorithm>
using namespace std;
const int N = 100010;
int a[N];
int main()
{
    
    int n;
    cin >> n;
    for(int i = 0;i < n;i ++) cin >> a[i];
    sort( a , a + n );
    int res = 0;
    for(int i = 0;i < n;i ++) res + = abs( a[i] - a[n/2] );
    cout << res;
    return 0;
}

欢迎点赞与评论~
记得收藏

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/weixin_52361979/article/details/118998306

智能推荐

RK3588快速上手 | 01-RK3588开发板快速上手_3588 开发板 wiki-程序员宅基地

文章浏览阅读2.3k次。RK3588是Rockchip最新推出的八核64位处理器(4核A76+4核A55),主频2.4GHz,集成GPU,内部集成6TOPS AI算力的NPU,多媒体方面支持到了8K视频编解码,_3588 开发板 wiki

Unity动画状态机Animator 与 Animation_状态机用animation还是animator-程序员宅基地

文章浏览阅读687次。https://blog.csdn.net/linxinfa/article/details/94392971有时候需要让美术做一些刚体位移动画, 那么美术在Unity中就要Project视图->Creat->Animation.但是这样创建出来的动画是新版动画,这样播放的话要需要AnimationController文件。 我就想用老版动画怎么办呢?如下图所示,选中刚刚创建的动画,然后在右边打开Debug模式,勾选legacy即可。如果是美术做的FBX动画,那么在这.._状态机用animation还是animator

Hbase之--------将Hdfs数据加载到Hbase数据库中_importjava.io.loexception; importorg.apache.hadoop-程序员宅基地

文章浏览阅读809次,点赞2次,收藏2次。package Kaoshi;import java.io.IOException;import org.apache.hadoop.conf.Configuration;import org.apache.hadoop.fs.FileSystem;import org.apache.hadoop.fs.Path;import org.apache.hadoop.hbase.HCol..._importjava.io.loexception; importorg.apache.hadoop.conf.configuration; i

linux中常用服务的安装-程序员宅基地

文章浏览阅读417次。安装环境:centos7.5配置离线yum源参考:https://blog.csdn.net/mayh554024289/article/details/54236336vi /etc/yum.conf 将 keepcache=0 改为 keepcache=1, 开启缓存功能缓存的包存放在cd /var/cache/yum/***/packages 利用缓存的包上传到打包环境机器,方便yum安..._linux如何安装服务包

控制面板设置java_win10系统打开java控制面板的具体技巧-程序员宅基地

文章浏览阅读4.8k次。win10系统使用久了,好多网友反馈说关于对win10系统打开java控制面板设置的方法,在使用win10系统的过程中经常不知道如何去对win10系统打开java控制面板进行设置,有什么好的办法去设置win10系统打开java控制面板呢?在这里小编教你只需要1、按开始按钮,或者是左下角的那个窗口的标志; 2、输入 JAVA控制面板这几个字,上面就会有相关的程序出现了;就搞定了。下面小编就给小伙伴们..._win10的java控制面板在哪里

python读取hdfs并返回dataframe教程_hdfs的dataframe转pandas的dataframe-程序员宅基地

文章浏览阅读1.1k次。更多编程教程请到:菜鸟教程 https://www.piaodoo.com/友情链接:高州阳光论坛https://www.hnthzk.com/人人影视http://www.sfkyty.com/ 不多说,直接上代码from hdfs import Clientimport pandas as pdHDFSHOST = “http://xxx:50070”FILENAME = “/tmp/preprocess/part-00000” #_hdfs的dataframe转pandas的dataframe

随便推点

怎么实现将Windows上的文件传到Linux、将Linux上的文件传输到Windows、不同的Linux设备之间文件传输_怎么把windows中的文件拖入linux中-程序员宅基地

文章浏览阅读2.4w次,点赞20次,收藏171次。本文基于Linux上CentOS 7版本和Windows 11专业版本配合Xshell 7演示三种传输方式怎么实现将Windows上的文件传到Linux、将Linux上的文件传输到Windows、不同的Linux设备之间文件传输使用rz和sz命令使用Xftp软件进行传输使用Sftp服务进行传输使用scp (-r)命令_怎么把windows中的文件拖入linux中

linux文件系统ext2\ext3\ext4\xfs详解_ext4、ext3、ext2、xfs-程序员宅基地

文章浏览阅读2.5k次。1.ext2介绍:第二代扩展文件系统是LINUX内核所用的文件系统,用以代替ext,是 EXT文件系统的升级版,特点:在ext2文件系统中,文件由inode(包含有文件的所有信息)进行唯一标识。一个文件可能对应多个文件名,只有在所有文件名都被删除后,该文件才会被删除。此外,同一文件在磁盘中存放和被打开时所对应的inode是不同的,并由内核负责同步。2.ext3介绍:EX..._ext4、ext3、ext2、xfs

matlab:字符向量、字符数组、字符串标量、字符串数组_matlab 字符串数组-程序员宅基地

文章浏览阅读8.8k次,点赞5次,收藏26次。matlab:字符向量、字符数组、字符串标量、字符串数组_matlab 字符串数组

qemu模拟arm嵌入式环境_qemu-system-arm-程序员宅基地

文章浏览阅读2.7k次。文章目录一、安装qemu二、安装arm工具链三、下载编译内核四、制作根文件系统五、qemu 运行1、直接启动kernel2、通过uboot启动内核2.1 配置QEMU Tap网络2.2 安装配置tftp2.3 编译uImage2.4 编写启动脚本boot.sh3. 挂载 NFS 文件系统六、qemu 模拟机连接外网七、其他1、制作多分区镜像2、运行qemu一、安装qemu1、下载编译安装# wget https://download.qemu.org/qemu-4.2.0.tar.xz# tar x_qemu-system-arm

眼睛慢慢眯成一条线的人都是实力很强劲的,教你在Unity中通过BlendShape来实现角色面部表情过渡切换(Animation)-程序员宅基地

文章浏览阅读1w次,点赞79次,收藏171次。在Unity项目中,我们可能需要实现3D角色表情的过渡切换,本文介绍了通过BlendShape来实现表情过渡切换的功能。_blendshape

前端跨域携带cookie_前端请求携带cookie-程序员宅基地

文章浏览阅读4k次,点赞2次,收藏4次。前端需要跨域携带cookie_前端请求携带cookie

推荐文章

热门文章

相关标签