贪心算法的运用

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

以找零钱为例,简单介绍一下贪心算法的应用
假设有一堆不同面额的硬币,现在需要用最少数量的硬币凑出某个金额。这时可以使用贪心算法来解决。

#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函数中调用它。该算法每次都选择面额最大的硬币来尽量多地凑出金额。这样就能保证所需硬币数量最小,这就是贪心算法的思想。

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

活动选择问题

#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;
}

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

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

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

也可以运用结构体

#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函数进行活动选择。

  • 20
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值