/*
1. 删数问题: 输入一个数A(例如2838594) 然后输入要删去的个数N(例如 3)
从数A中删除N个位,使得剩下的结果是最小的(如2354)
2. 有一容量为200的背包。有8种物品,每种的体积和价值如下表。设每种物品都可以取任意数量,
求一种方法使得装进背包的物品的价值总和最大。
A B C D E F G H
40 55 20 55 30 40 45 55
35 20 20 40 35 15 40 20
*/
#include <stdio.h>
#include <string.h>
// ------------------ 第1题 -----------------
// 从前n个数字字母中拿走最小的数字, 返回那个被移除的最小数字
// "28318594" -> 取走"1",剩下"8594"
static char take_minimum(char* buf, int n)
{
int len = strlen(buf);
if(n > len) n = len;
char min = '9' + 1;
int pos = -1;
for(int i=0; i<n; i++)
{
char ch = buf[i];
if(ch < min)
{
min = ch;
pos = i;
}
}
// 删除前面的数字
memmove(buf, buf + pos + 1, len - pos);
return min;
}
static int ex_1(int a, int n)
{
// 把a转成字符串, 得到长度
char buf[32] = {0};
sprintf(buf, "%d", a);
int size = strlen(buf);
// 转换问题, 从a中取m个数, m = size - n
int m = size - n;
// 从a中删除n个位置,使剩余的结果最小
while(m > 0)
{
// 每次都在前面几个数中取最小的一个,此为完备算法
// 可能不算是"贪心算法"
char min = take_minimum(buf, strlen(buf) - (m-1));
printf("%c", min); // 打印被取走的数字
m --;
}
return 0;
}
// ------------------ 第2题 -----------------
struct Object
{
char label; // 标签
int volumn; // 体积
int value; // 价值
float ratio; // 价值体积比
int count; // 填入的数量
};
static int ex2()
{
/*
A B C D E F G H
40 55 20 55 30 40 45 55
35 20 20 40 35 15 40 20
*/
int MAX_VOLUMN = 200;
int i;
// 使用匿名struct,反正是局部用的
Object objs[8] =
{
{ 'A', 40, 35, 0.0f, 0 },
{ 'B', 55, 20, 0.0f, 0 },
{ 'C', 20, 20, 0.0f, 0 },
{ 'D', 55, 40, 0.0f, 0 },
{ 'E', 30, 35, 0.0f, 0 },
{ 'F', 40, 15, 0.0f, 0 },
{ 'G', 45, 40, 0.0f, 0 },
{ 'H', 55, 20, 0.0f, 0 }
};
// 计算性价比
for(i=0; i<8; i++)
{
objs[i].ratio = (float) objs[i].value / objs[i].volumn;
}
// 排序:按性价比,即value/volumn越大越好, 按ratio从高到低排列
// 选择排序
for(i=0; i<7; i++)
{
int maxobj = i;
for(int j=i+1; j<8; j++)
{
if(objs[j].ratio > objs[maxobj].ratio)
maxobj = j;
}
// 交换
if(maxobj != i)
{
Object temp = objs[maxobj];
objs[maxobj] = objs[i];
objs[i] = temp;
}
}
// 贪心法,每次都取性价比最高的来填充
int total_volumn = 0; // 已占的容量
for(i=0; i<8; i++)
{
if(total_volumn >= MAX_VOLUMN) break;
Object* obj = &objs[i]; // 按性价比顺序取obj
int volumn = MAX_VOLUMN - total_volumn; // 剩余容量
int num = volumn / obj->volumn; // 可以放几个?
obj->count = num;
total_volumn += num * obj->volumn;
printf("放入:%c,数量:%d x %d, 总容量:%d\n"
,obj->label, num, obj->volumn, total_volumn);
}
return 0;
}
int main()
{
// char s[] = "28318594";
// char ch = take_minimum(s, 5);
if(0)
{
// 第1题测试
// 输入一个正整数数
int a = 0;
printf("a=");
scanf("%d", &a);
// 输入要删除的位数
int n = 0;
printf("n=");
scanf("%d", &n);
ex_1(a, n);
}
if(1)
{
// 第2题测试
ex2();
}
return 0;
}
C++作业: 贪心法求解问题
最新推荐文章于 2024-03-26 18:06:24 发布