贪心算法的运用

贪心算法(Greedy Algorithm)是一种常用的算法思想,通常用来解决最优化问题。可以使用贪心算法来解决一些问题,例如找零钱、任务调度等。

以找零钱为例,简单介绍一下贪心算法的应用

假设有一堆不同面额的硬币,现在需要用最少数量的硬币凑出某个金额。这时可以使用贪心算法来解决。

c 复制代码
#include <stdio.h>

void findMinCoins(int coins[], int n, int amount) {
    int count = 0;
    printf("使用的硬币面额为:");
    // 从面额最大的硬币开始尽可能多地使用
    for (int i = 0; i < n; i++) {
        while (amount >= coins[i]) {
            amount -= coins[i];
            count++;
            printf("%d ", coins[i]);
        }
    }
    printf("\n总共使用了 %d 枚硬币\n", count);
}

int main() {
    int coins[] = {25, 10, 5, 1};  // 硬币的面额
    int n = sizeof(coins) / sizeof(coins[0]);
    int amount = 93;  // 需要凑出的金额

    findMinCoins(coins, n, amount);

    return 0;
}

我们定义了一个findMinCoins函数来找零,并在main函数中调用它。该算法每次都选择面额最大的硬币来尽量多地凑出金额。这样就能保证所需硬币数量最小,这就是贪心算法的思想。

在实际应用中,贪心算法可能不适用于所有场景,但对于特定类型的问题,它是一种简单而高效的解决方案。

活动选择问题

c 复制代码
#include <stdio.h>

// 假设活动已经按照结束时间非降序排列
void activitySelection(int start[], int finish[], int n) {
    printf("Following activities are selected:\n");
    
    // 第一个活动总是被选中
    int i = 0;
    printf("%d ", i);

    // 对剩下的活动进行遍历
    for (int j = 1; j < n; j++) {
        // 如果这个活动的开始时间大于或等于上一个活动的结束时间,那么选择这个活动
        if (start[j] >= finish[i]) {
            printf("%d ", j);
            i = j;
        }
    }
}

int main() {
    int start[] = {1, 3, 0, 5, 8, 5};
    int finish[] = {2, 4, 6, 7, 9, 9};
    int n = sizeof(start) / sizeof(start[0]);

    activitySelection(start, finish, n);
    return 0;
}

在这个例子中,我们首先将活动按照结束时间非降序排列,然后从第一个活动开始,依次检查后续活动的开始时间是否满足条件。

如果满足条件,就选择该活动并更新当前活动的索引。活动选择问题是一个典型的可以通过贪心算法解决的问题,基本思路是每一步都做出一个局部最优的选择,以期望最终能得到全局最优解。

贪心算法的活动选择问题是一个经典的应用场景,通常涉及到安排一系列活动,每个活动都有一个开始时间和结束时间,而资源(例如会议室)只能同时被一个活动使用。目标是安排出尽可能多的互不相交的活动。

也可以运用结构体

c 复制代码
#include <stdio.h>

// 活动结构体,包含开始时间和结束时间
struct Activity {
    int start;
    int finish;
};

// 将活动按照结束时间非降序排列的比较函数
int compare(const void *a, const void *b) {
    return (((struct Activity *)a)->finish - ((struct Activity *)b)->finish);
}

// 贪心算法解决活动选择问题
void activitySelection(struct Activity arr[], int n) {
    printf("Following activities are selected:\n");
    
    // 第一个活动总是被选中
    int i = 0;
    printf("%d ", i);

    // 对剩下的活动进行遍历
    for (int j = 1; j < n; j++) {
        // 如果这个活动的开始时间大于或等于上一个活动的结束时间,那么选择这个活动
        if (arr[j].start >= arr[i].finish) {
            printf("%d ", j);
            i = j;
        }
    }
}

int main() {
    struct Activity arr[] = {{1, 2}, {3, 4}, {0, 6}, {5, 7}, {8, 9}, {5, 9}};
    int n = sizeof(arr) / sizeof(arr[0]);

    // 按照结束时间非降序排列
    qsort(arr, n, sizeof(arr[0]), compare);

    activitySelection(arr, n);
    return 0;
}

在这个例子中,我们首先定义了一个包含开始时间和结束时间的活动结构体,并实现了一个按照结束时间非降序排列的比较函数。然后使用贪心算法来解决活动选择问题,在主函数中定义了一些活动并按照结束时间排序,然后调用activitySelection函数进行活动选择。

相关推荐
炸膛坦客8 分钟前
单片机/C/C++八股:(二十三)#define 和 typedef 的区别
c语言·c++·单片机
捷瑞电子工坊2 小时前
C语言取地址符 `&` 极简教程
c语言·c语言基础·取地址符·指针入门
乱七八糟的屋子3 小时前
LibYAML超全教程-C语言YAML解析与生成
c语言·开发语言·配置文件·yaml解析·libyaml·开源库实战
小肝一下3 小时前
2. 顺序表和链表
c语言·数据结构·c++·链表·dijkstra·依蕾娜·香香的依蕾娜
j7~3 小时前
【数据结构初阶】带头双向循环链表 (DSList) --增删查改完整实现详解
c语言·数据结构·链表·带头双向循环链表
无相求码20 小时前
【C语言】字符串的本质是什么,为什么 strlen 会读到野内存
c语言·开发语言
LuminousCPP1 天前
C 语言集中实践全记录:顺序表 + 单链表原理实现与通讯录项目实战【附可运行源码】
c语言·开发语言·数据结构·经验分享·笔记
SuperByteMaster1 天前
__set_MSP 和__set_MSPLIM 接口区别
c语言
CS创新实验室1 天前
NumPy数组的C风格和Fortran风格
c语言·开发语言·numpy
LuminousCPP1 天前
单链表专题(应用篇):三道经典题吃透删除、反转与快慢指针
c语言·数据结构·笔记