mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-25 13:26:30 +08:00
feat: add C code in chapter_greedy (#755)
* add fractional_knapsack.c * update CMakeLists * add c code in chapter_greedy * fix header format * format code by clang-format * remove extra comments * replace ternary operator to MACRO * parameters form adjustment * Update fractional_knapsack.c * Update max_capacity.c * Update max_product_cutting.c * add comments for consistency with cpp ver * move MIN&MAX macro to source file * typo fix --------- Co-authored-by: Yudong Jin <krahets@163.com>
This commit is contained in:
parent
af65ab08ef
commit
d225b416cf
5 changed files with 147 additions and 0 deletions
|
@ -1 +1,4 @@
|
||||||
add_executable(coin_change_greedy coin_change_greedy.c)
|
add_executable(coin_change_greedy coin_change_greedy.c)
|
||||||
|
add_executable(fractional_knapsack fractional_knapsack.c)
|
||||||
|
add_executable(max_capacity fractional_knapmax_capacitysack.c)
|
||||||
|
add_executable(max_product_cutting max_product_cutting.c)
|
||||||
|
|
62
codes/c/chapter_greedy/fractional_knapsack.c
Normal file
62
codes/c/chapter_greedy/fractional_knapsack.c
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
/**
|
||||||
|
* File: fractional_knapsack.c
|
||||||
|
* Created Time: 2023-09-14
|
||||||
|
* Author: xianii (xianyi.xia@outlook.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../utils/common.h"
|
||||||
|
|
||||||
|
/* 物品 */
|
||||||
|
struct item {
|
||||||
|
int w; // 物品重量
|
||||||
|
int v; // 物品价值
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef struct item Item;
|
||||||
|
|
||||||
|
/* 按照价值密度排序 */
|
||||||
|
int sortByValueDensity(const void *a, const void *b) {
|
||||||
|
Item *t1 = (Item *)a;
|
||||||
|
Item *t2 = (Item *)b;
|
||||||
|
return (float)(t1->v) / t1->w < (float)(t2->v) / t2->w;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 分数背包:贪心 */
|
||||||
|
float fractionalKnapsack(int wgt[], int val[], int itemCount, int cap) {
|
||||||
|
// 创建物品列表,包含两个属性:重量、价值
|
||||||
|
Item *items = malloc(sizeof(Item) * itemCount);
|
||||||
|
for (int i = 0; i < itemCount; i++) {
|
||||||
|
items[i] = (Item){.w = wgt[i], .v = val[i]};
|
||||||
|
}
|
||||||
|
// 按照单位价值 item.v / item.w 从高到低进行排序
|
||||||
|
qsort(items, (size_t)itemCount, sizeof(Item), sortByValueDensity);
|
||||||
|
// 循环贪心选择
|
||||||
|
float res = 0.0;
|
||||||
|
for (int i = 0; i < itemCount; i++) {
|
||||||
|
if (items[i].w <= cap) {
|
||||||
|
// 若剩余容量充足,则将当前物品整个装进背包
|
||||||
|
res += items[i].v;
|
||||||
|
cap -= items[i].w;
|
||||||
|
} else {
|
||||||
|
// 若剩余容量不足,则将当前物品的一部分装进背包
|
||||||
|
res += (float)cap / items[i].w * items[i].v;
|
||||||
|
cap = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
free(items);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Driver Code */
|
||||||
|
int main(void) {
|
||||||
|
int wgt[] = {10, 20, 30, 40, 50};
|
||||||
|
int val[] = {50, 120, 150, 210, 240};
|
||||||
|
int capacity = 50;
|
||||||
|
|
||||||
|
// 贪心算法
|
||||||
|
float res = fractionalKnapsack(wgt, val, sizeof(wgt) / sizeof(int), capacity);
|
||||||
|
printf("不超过背包容量的最大物品价值为 %0.2f\n", res);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
43
codes/c/chapter_greedy/max_capacity.c
Normal file
43
codes/c/chapter_greedy/max_capacity.c
Normal file
|
@ -0,0 +1,43 @@
|
||||||
|
/**
|
||||||
|
* File: max_capacity.c
|
||||||
|
* Created Time: 2023-09-15
|
||||||
|
* Author: xianii (xianyi.xia@outlook.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../utils/common.h"
|
||||||
|
|
||||||
|
#define MIN(a, b) (a < b ? a : b)
|
||||||
|
#define MAX(a, b) (a > b ? a : b)
|
||||||
|
|
||||||
|
/* 最大容量:贪心 */
|
||||||
|
int maxCapacity(int ht[], int htLength) {
|
||||||
|
// 初始化 i, j 分列数组两端
|
||||||
|
int i = 0;
|
||||||
|
int j = htLength - 1;
|
||||||
|
// 初始最大容量为 0
|
||||||
|
int res = 0;
|
||||||
|
// 循环贪心选择,直至两板相遇
|
||||||
|
while (i < j) {
|
||||||
|
// 更新最大容量
|
||||||
|
int capacity = MIN(ht[i], ht[j]) * (j - i);
|
||||||
|
res = MAX(res, capacity);
|
||||||
|
// 向内移动短板
|
||||||
|
if (ht[i] < ht[j]) {
|
||||||
|
i++;
|
||||||
|
} else {
|
||||||
|
j--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Driver Code */
|
||||||
|
int main(void) {
|
||||||
|
int ht[] = {3, 8, 5, 2, 7, 7, 3, 4};
|
||||||
|
|
||||||
|
// 贪心算法
|
||||||
|
int res = maxCapacity(ht, sizeof(ht) / sizeof(int));
|
||||||
|
printf("最大容量为 %d\n", res);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
38
codes/c/chapter_greedy/max_product_cutting.c
Normal file
38
codes/c/chapter_greedy/max_product_cutting.c
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
/**
|
||||||
|
* File: max_product_cutting.c
|
||||||
|
* Created Time: 2023-09-15
|
||||||
|
* Author: xianii (xianyi.xia@outlook.com)
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "../utils/common.h"
|
||||||
|
|
||||||
|
/* 最大切分乘积:贪心 */
|
||||||
|
int maxProductCutting(int n) {
|
||||||
|
// 当 n <= 3 时,必须切分出一个 1
|
||||||
|
if (n <= 3) {
|
||||||
|
return 1 * (n - 1);
|
||||||
|
}
|
||||||
|
// 贪心地切分出 3 ,a 为 3 的个数,b 为余数
|
||||||
|
int a = n / 3;
|
||||||
|
int b = n % 3;
|
||||||
|
if (b == 1) {
|
||||||
|
// 当余数为 1 时,将一对 1 * 3 转化为 2 * 2
|
||||||
|
return pow(3, a - 1) * 2 * 2;
|
||||||
|
}
|
||||||
|
if (b == 2) {
|
||||||
|
// 当余数为 2 时,不做处理
|
||||||
|
return pow(3, a) * 2;
|
||||||
|
}
|
||||||
|
// 当余数为 0 时,不做处理
|
||||||
|
return pow(3, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Driver Code */
|
||||||
|
int main(void) {
|
||||||
|
int n = 58;
|
||||||
|
// 贪心算法
|
||||||
|
int res = maxProductCutting(n);
|
||||||
|
printf("最大切分乘积为 %d\n", res);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -13,6 +13,7 @@
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
|
#include <math.h>
|
||||||
|
|
||||||
#include "list_node.h"
|
#include "list_node.h"
|
||||||
#include "print_util.h"
|
#include "print_util.h"
|
||||||
|
|
Loading…
Reference in a new issue