贪心算法之装箱问题:
有若干个体积为V的箱子,有n个物品体积为v1,v2,v3,v4。。。。
要求:将所有物品装入箱子中,使打开的箱子尽可能少。
算法描述:把所有物品按体积降序排序,每次取出一个物品(该物品为当前体积最大的物品),遍历所有已打开箱子,将该箱子放入一个较早打开的箱子,若没有箱子能放下,则打开一个新箱子。
#include <stdio.h>
#include <stdlib.h>
#define V 10;
typedef struct/* 定义物品 */
{
int gno;//物品编号
int gv;//物品体积
}ElemG;
typedef struct node//定义物品链
{
int gno;
struct node* link;
}Goodslink;
typedef struct Box //定义箱子链
{
int remainder;
Goodslink *hg;//指向物品链头指针
struct Box *next;
}Boxlink;
ElemG* sort(ElemG *g,int n);
Boxlink* Package(ElemG *g,int n);
void Printbox(Boxlink* box);
ElemG* sort(ElemG *g,int n)
{
ElemG *temp;
temp=(ElemG*)malloc(sizeof(ElemG));
for(int i=0;i<n-1;i++)
{
for(int j=i+1;j<n;j++)
{
if(g[j].gv>g[i].gv)
{
*temp=g[i];//g[i]是Elem 形式的元素
g[i]=g[j];
g[j]=*temp;
}
}
}
return g;
}
Boxlink* Package(ElemG *g,int n)
{
//定义头指针,尾指针,跑链的p 头指针要空,
Boxlink *bh=NULL,*tail,*p;
//跑物品链的q newg指向新的链
Goodslink *q,*newg;
//遍历n个物品
for(int i=0;i<n;i++)
{
//p从头节点开始遍历,
for(p=bh;p&&p->remainder<g[i].gv;p=p->next);
if(!p)
{
p=(Boxlink*)malloc(sizeof(Boxlink));
//初始化箱子 体积剩余为V p指向空
p->remainder=V;
p->next=NULL;
p->hg=NULL;
if(!bh) bh=tail=p;//头指针为空建好第一个节点
else tail=tail->next=p;//头指针不为空挂链
}
//挂箱子链后完善物品信息
p->remainder-=g[i].gv;
newg=(Goodslink*)malloc(sizeof(Goodslink));
//给物品链节点初始化
newg->gno=g[i].gno;
newg->link=NULL;
//给物品链挂链
//当箱子的物品链头指针为空,则
if(!p->hg)
{
p->hg=newg;
}
else{
for(q=p->hg;q->link!=NULL;q=q->link);
//遍历完成,挂物品链
q->link=newg;
}
}
return bh;
}
void Printbox(Boxlink* bh)
{
int i=0;
Boxlink *p;//便利箱子
Goodslink *q;//便利物品
for(p=bh;p;p=p->next)
{
printf("输出第%d个箱子",++i);
for(q=p->hg;q;q=q->link)
{
printf("%5d",q->gno);
}
printf("\n");
}
}
void PrintGoods(ElemG *h,int n)
{
printf("打印物品");
for(int i=0;i<n;i++)
{
printf("%d",h[i].gno);
}
}
int main()
{
//定义物品
ElemG *g;
//定义箱子头指针
Boxlink* bh;
int n,w;//定义物品个数定义物品体积
printf("请输入物品个数");
scanf("%d",&n);
g=(ElemG*)malloc(sizeof(ElemG));
printf("输入%d个物体的体积\n",n);
for(int i=0;i<n;i++)
{
g[i].gno=i+1;
scanf("%d",&w);
g[i].gv=w;
}
//排序
g=sort(g,n);
PrintGoods(g,n);
//装箱
bh=Package(g,n);
//打印
Printbox(bh);
//释放
free(g);
free(bh);
}