C语言实现:贪心算法

算法基础原理

 贪心算法是一种在求解问题时,总是做出在当前看来是最好的选择的算法。它不从整体最优上进行考虑,而是通过每一步的局部最优选择,希望达到全局的最优解.

贪心算法的特点:贪心算法在每一步都选择当前状态下的最优解,即局部最优解,同时贪心算法采用自顶向下的方式,以迭代的方法做出相继的贪心选择,每做一次贪心选择,就将所求问题简化为一个规模更小的子问题。虽然每一步都保证能获得局部最优解,但由此产生的全局解有时不一定是最优的,所以贪心算法不要回溯。

贪心算法包含以下几种分支:

  1. 标准贪心算法
    • 活动选择问题:选择最大数量的不重叠活动。
    • 埃及分数问题:将真分数表示为一系列不重复的倒数之和。
    • 霍夫曼编码:用于数据压缩,构建最优前缀码。
    • 水连接问题:用最少的管子连接所有的房子。
  2. 图中的贪心算法
    • Kruskal的最小生成树算法:通过不断加入最小的边来构建最小生成树。
    • Prim的最小生成树算法:从一个顶点开始,每次加入连接已选顶点和未选顶点之间的最小边。
    • Dijkstra的最短路径算法:用于找到图中单源最短路径。
  3. 数组中的贪心算法
    • 数组的最小乘积子集问题:选择数组中某些数,使得它们的乘积最小。
    • 最大化数组总和问题:在限定操作次数下最大化数组的总和。
    • 其他与数组相关的最大化或最小化问题,如最大化连续差异的总和等。

贪心算法的基础流程如下: 

代码实现 

金钱找零 

先定义一个包含四种面值纸币的数组coins和一个记录每种硬币数量的数组coin_countgreedyChange函数接收一个整数money作为输入,表示需要找零的金额。函数通过遍历coins数组,从最大面值的纸币开始,尽可能多地使用每种面值的纸币,直到找零完成或无法找零。如果找零成功,它会打印出总共需要的纸币数量和每种面值纸币的数量;如果无法找零,它会打印出“无法找零”。最后main函数从用户那里获取要找零的金额,并调用greedyChange函数进行处理。

#include <stdio.h>  
  
// 定义可用纸币面值  
int coins[] = {20, 10, 5, 1};  
#define NUM_COINS 4 // 定义需要纸币的数量  
int coin_count[NUM_COINS] = {0}; // 设置一个全局变量用于记录每种硬币的数量  
  
void greedyChange(int money) {  
    int i, count = 0;  
    for (i = 0; i < NUM_COINS; i++) { // 使用NUM_COINS宏   
        while (money >= coins[i]) {  
            money -= coins[i];  
            coin_count[i]++; // 修改全局变量,不需要前缀global_  
            count++;  
        }  
    }  
    if (money != 0) {  
        printf("无法找零\n");  
        return;  
    }  
    printf("总共需要 %d 张money\n", count);  
    for (i = 0; i < NUM_COINS; i++) { 
        if (coin_count[i] != 0) {  
            printf("面值 %d 的纸币需要 %d 张\n", coins[i], coin_count[i]);  
        }  
    }  
    // 清零全局的coin_count数组以供下次使用  
    for (i = 0; i < NUM_COINS; i++) { 
        coin_count[i] = 0;  
    }  
}  
  
int main() {  
    int money;  
    printf("请输入要找零的金额: ");  
    scanf("%d", &money);  
    greedyChange(money);  
    return 0;  
}

计算连续插值的最大和

先提示用户输入数组元素的数量,并动态分配相应大小的内存来存储这些元素。接着要求用户输入指定数量的整数,并将这些整数存储在之前分配的数组中。然后调用maxDifferenceSum函数来计算数组中任意两个连续元素之间差值的绝对值之和的最大值。这个函数通过两层循环遍历数组,外层循环确定起始位置,内层循环计算从当前起始位置到数组末尾的所有连续差值的绝对值之和,并在过程中更新最大和。最后打印出连续差值的最大和,并释放之前动态分配的内存。 

#include <stdio.h>  
#include <stdlib.h>  
#include <math.h>  
  
int maxDifferenceSum(int arr[], int n) {  
    int maxSum = 0;  
    for (int i = 0; i < n; i++) {  
        int currentSum = 0;  
        for (int j = i; j < n - 1; j++) {  
            currentSum += abs(arr[j] - arr[j + 1]);  
            if (currentSum > maxSum) {  
                maxSum = currentSum;  
            }  
        }  
    }  
    return maxSum;  
}  
  
int main() {    
    int n;  
    printf("请输入数组元素的数量: ");  
    scanf("%d", &n);  
  
    // 动态分配数组内存  
    int *arr = (int *)malloc(n * sizeof(int));  
    if (arr == NULL) {  
        printf("内存分配失败!\n");  
        return 1;  
    }  
  
    printf("请输入 %d 个整数:\n", n);  
    for (int i = 0; i < n; i++) {  
        scanf("%d", &arr[i]);  
    }  
  
    int result = maxDifferenceSum(arr, n);    
    printf("连续差值的最大和为: %d\n", result);    
    // 释放动态分配的内存  
    free(arr);  
  
    return 0;    
}

流程图的Markdown mermaid代码

基础流程: 

graph TB  
    A[开始]  
    B[初始化候选集合]  
    C[选择当前最优解]  
    D[更新候选集合]  
    E[判断候选集合是否为空]  
    F[是,算法结束]  
    G[否,继续选择]  
    H[将当前最优解加入结果集]  
  
    A --> B  
    B --> C  
    C --> H  
    H --> D  
    D --> E  
    E --> F  
    E --> G  
    G --> C

 C语言实现找零钱流程:

graph TB  
    A["开始"]  
    B["输入要找零的金额"]  
    C["调用greedyChange函数"]  
    D["初始化count为0"]  
    E["遍历每种纸币面值"]  
    F["当前纸币面值能否找零"]  
    G["减去当前纸币面值,增加纸币计数,增加count"]  
    H["判断是否仍有余额需要找零"]  
    I["输出无法找零"]  
    J["输出总纸币张数"]  
    K["输出每种纸币的面值和数量"]  
    L["清零全局coin_count数组"]  
    M["结束"]  
  
    A --> B  
    B --> C  
    C --> D  
    D --> E  
    E --> F  
    F -->|是| G  
    G --> H  
    F -->|否| H  
    H -->|仍有余额| I  
    H -->|无余额| J  
    J --> K  
    K --> L  
    L --> M  
    I --> M

C语言计算连续插值的最大和

graph TB  
    A[开始]  
    B[提示用户输入数组元素数量]  
    C[读取用户输入的数组元素数量]  
    D[动态分配数组内存]  
    E[检查内存分配是否成功]  
    F[内存分配失败]  
    G[提示用户输入指定数量的整数]  
    H[读取用户输入的整数并存入数组]  
    I[调用maxDifferenceSum函数计算连续差值的最大和]  
    J[打印连续差值的最大和]  
    K[释放动态分配的内存]  
    L[结束]  
  
    A --> B  
    B --> C  
    C --> D  
    D --> E  
    E --> |成功| G  
    E --> |失败| F  
    F --> L  
    G --> H  
    H --> I  
    I --> J  
    J --> K  
    K --> L

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

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

相关文章

SSH的基本使用

文章目录 1. SSH使用介绍2. 如何配置OpenSSH Client和OpenSSH Server2.1 Windows系统配置2.2 Linux系统配置2.2.1. 安装OpenSSH服务2.2.2. 启动和检查SSH服务 3. SSH具体使用方式4. vscode中使用ssh远程连接 1. SSH使用介绍 SSH 最常见的用途是通过加密连接在不安全的网络中进…

fiddler抓https包

1&#xff0c;安装fiddler省略 2&#xff0c;下载证书步骤&#xff1a;tools-options-https 点击确认&#xff0c;点击OK&#xff0c;点击是 把证书安装到谷歌浏览器上步骤&#xff1a;点击谷歌浏览器右上角的设置&#xff0c;在搜索框中搜索证书&#xff0c;点击“证书管理”…

常见的排序算法【总结】

目录 排序的基本概念与分类排序的稳定性内排序与外排序简单排序冒泡排序时间复杂度&#xff1a; O ( n 2 ) O(n^2) O(n2) 简单选择排序排序原理&#xff1a;时间复杂度&#xff1a; O ( n 2 ) O(n^2) O(n2) 插入排序排序原理&#xff1a;时间复杂度&#xff1a; O ( n 2 ) O(n^…

MFC GDI绘制卡通人物

文章目录 主要代码完整visual studio工程下载 主要代码 // DrawFrogView.cpp : implementation of the CDrawFrogView class //#include "stdafx.h" #include "DrawFrog.h"#include "DrawFrogDoc.h" #include "DrawFrogView.h"#inclu…

让TSN DDS运转起来——面向智能汽车的以太网测试解决方案

概述 作为OPEN联盟和AUTOSAR联盟的核心成员&#xff0c;经纬恒润多年来持续为国内外各大OEM和供应商提供车载以太网相关的咨询服务&#xff0c;涵盖TCP/IP、SOME/IP、DDS、诊断、TSN等前沿技术领域的设计和测试。同时&#xff0c;经纬恒润与行业内的合作伙伴紧密合作&#xff0…

Vulnhub靶场DC-4练习

目录 0x00 准备0x01 主机信息收集0x02 站点信息收集0x03 漏洞查找与利用1. 爆破登录2. 命令执行3. 反弹shell4. hydra爆破ssh5. 提权 0x04 总结 0x00 准备 下载链接&#xff1a;https://download.vulnhub.com/dc/DC-4.zip 介绍&#xff1a; DC-4 is another purposely built …

【精品案例】数字孪生技术与数字工厂案例(59页PPT)

引言&#xff1a;随着工业4.0和智能制造的快速发展&#xff0c;数字孪生技术和数字工厂已成为制造业转型升级的重要趋势。数字孪生技术通过构建虚拟的数字模型&#xff0c;实现对物理实体全生命周期的映射与仿真&#xff0c;为企业的产品研发、设计、制造等提供有力支持。而数字…

如何评估SD-WAN专线带宽、确保网络性能

网络带宽的充足与否直接关系到业务的正常运作和用户的使用体验。为了确保最佳效果&#xff0c;SD-WAN专线的带宽需要根据企业的规模和具体网络需求进行详细评估。评估过程中需充分考虑实时应用、用户数量、分支机构间的连接以及业务特点。本文将探讨以下问题&#xff1a;SD-WAN…

基于Java的4S店车辆管理系统

你好&#xff0c;我是计算机专业的毕业生&#xff0c;很高兴与您分享我的毕业设计。 开发语言&#xff1a;Java 数据库&#xff1a;MySQL 技术&#xff1a;Java、SpringBoot、B/S模式 工具&#xff1a;MyEclipse、MySQL 系统展示 首页 个人中心 销售员管理界面 车辆维修管…

Ubuntu安装NVIDIA驱动

目录 安装gcc 安装NVIDIA驱动 检查nvidia显卡型号 根据显卡型号下载对应的驱动 安装命令 如何卸载 安装gcc 安装显卡驱动需要使用gcc&#xff0c;输入命令检查是否有gcc gcc --version 如果有版本号弹出&#xff0c;说明已经有gcc环境了&#xff0c;没有的则运行以下…

【Docker】存储数据卷

目录 1、挂载数据卷到容器里 2、查询挂载文件 3、容器与主机之间映射共享卷 4、三个容器之间使用共享卷 5、卷数据的备份与恢复 5.1 备份 5.2 恢复 1、挂载数据卷到容器里 docker run -itd --name test02 -v /data nginx docker exec -it test02 bashls / docker inspe…

1.8 HTTP协议结构

我们来看一下HTTP协议到底由哪些部分组成&#xff0c;也就是HTTP协议的结构。知道了这些知识才能在接口测试中游刃有余。 我们看上图&#xff0c;HTTP协议由四部分组成 起始行 描述请求和响应的基本信息。 当是请求时&#xff1a;请求方法是GET&#xff0c;调用的地址&#…

python基础篇(5):None类型

1 None类型 Python中有一个特殊的字面量&#xff1a;None&#xff0c;其类型是&#xff1a;<class NoneType> 无返回值的函数&#xff0c;实际上就是返回了&#xff1a;None这个字面量 None表示&#xff1a;空的、无实际意义的意思 函数返回的None&#xff0c;就表示…

【Linux】使用信号进行进程间通信

&#x1f525;博客主页&#xff1a; 我要成为C领域大神&#x1f3a5;系列专栏&#xff1a;【C核心编程】 【计算机网络】 【Linux编程】 【操作系统】 ❤️感谢大家点赞&#x1f44d;收藏⭐评论✍️ 本博客致力于知识分享&#xff0c;与更多的人进行学习交流 ​ ​ 实现原理&a…

深入理解桥接模式(Bridge Pattern)及其实际应用

引言 在软件开发过程中&#xff0c;设计模式为我们提供了优雅且高效的解决方案&#xff0c;以应对常见的设计问题。桥接模式&#xff08;Bridge Pattern&#xff09;作为一种结构型设计模式&#xff0c;旨在将抽象部分与其实现部分分离&#xff0c;使它们可以独立变化&#xf…

MySQL 面试突击指南:核心知识点解析2

事务并发可能引发的问题 MySQL 是一个客户端/服务器架构的软件,对于同一个服务器来说,可以有多个客户端与之连接,每个客户端与服务器连接后,可以称为一个会话(Session)。每个客户端都可以在自己的会话中向服务器发出请求语句,一个请求语句可能是某个事务的一部分,也就…

shell:使用结构化语句(控制流)

许多程序要求对shell脚本中的命令施加一些逻辑流程控制。有一类命令会根据条件使脚本跳 过某些命令。这样的命令通常称为结构化命令(structured command)。 1. if-then、if-then-else、if-then-elif-else 如果该命令的退出状态码是0 (该命令成功运行)&#xff0c;位于then部分…

grpc学习golang版( 二、入门示例)

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 文章目录 一、环境二、编写protobuf文件三、编写server服务端四、编写服务端五、测试 一、环境 确保环境已经配置完成&#xff0c;效果如下。不同环境可能导致后续生成的效果不一。 go version protoc --version…

GPT-5:AI新纪元的领航者,多维度的审视与准备

一、引言&#xff1a;GPT-5与AI的多维演进 GPT-5作为AI领域的里程碑式突破&#xff0c;不仅仅代表了技术的飞跃&#xff0c;更预示着社会、文化以及经济等多个层面的深刻变革。从技术的角度看&#xff0c;GPT-5代表着AI在自然语言处理领域的最新高度&#xff1b;而从更宽广的视…

Kafka基本架构

「kafka设计思想」 一个最基本的架构是生产者发布一个消息到Kafka的一个Topic &#xff0c;该Topic的消息存放于的Broker中&#xff0c;消费者订阅这个Topic&#xff0c;然后从Broker中消费消息&#xff0c;下面这个图可以更直观的描述这个场景&#xff1a; 「消息状态&#x…