装箱问题的贪心准则:
1.将物品体积从大到小排列
2.遍历箱子,将物品放入一个较早打开的且剩余空间足够的箱子,否则开新箱子
结点类型:
typedef struct goodnode{
int gno;
int v;
}Goods; //物品信息结点
typedef struct GoodNode{
int gno;
struct GoodNode *next;
}GNode; //物品链结点
typedef struct BoxNode{
int reminder;
GNode *h;
struct BoxNode *next;
}BNode; //箱子链结点
排序(这里使用希尔排序)
void Swap(Goods *p,Goods *q){
int gno,v;
gno=p->gno;
v=p->v;
p->gno=q->gno;
p->v=q->v;
q->gno=gno;
q->v=v;
q->gno=gno;
}
void ShellSort(Goods *g,int n){ //物品信息存在数组g中,n为物品个数
int gap,i,j;
int tv,tno;
for(gap=n/2;gap>0;gap/=2){
for(i=gap;i<n;i++){
if(g[i].v>g[i-gap].v){
tv=g[i].v;
tno=g[i].gno;
j=i-gap;
while(j>=0&&g[j].v<tv){
Swap(g+j+gap,g+j);
j=j-gap;
}
g[j+gap].gno=tno;
g[j+gap].v=tv;
}
}
}
}
开箱子放物品
BNode* CreateBox(Goods *g,int n,int v){
BNode *h,*pb,*t;
GNode *pg,*p;
int i;
h=NULL;
for(i=0;i<n;i++){
pg=(GNode*)malloc(sizeof(GNode)); //创建物品链结点
pg->gno=g[i].gno;
pg->next=NULL;
for(pb=h;pb&&pb->reminder<g[i].v;pb=pb->next); //找到可以放当前物品的箱子,若p==NULL,则表示开新箱子
if(pb==NULL){ //开新箱子
pb=(BNode*)malloc(sizeof(BNode));
pb->h=NULL;
pb->reminder=v;
pb->next=NULL;
if(h==NULL) //挂箱子链
t=h=pb;
else
t=t->next=pb;
}
if(pb->h==NULL) //挂物品链
pb->h=pg;
else{
for(p=pb->h;p->next;p=p->next);
p->next=pg;
}
pb->reminder-=g[i].v;
}
return h;
}
输出每个箱子中存储物品的编号
void PrintBox(BNode *h){
BNode *pb;
GNode *pg;
for(pb=h;pb;pb=pb->next){
for(pg=pb->h;pg;pg=pg->next)
printf("%d\t",pg->gno);
printf("\n");
}
}
主函数
int main(void){
int i,n;
int v;
Goods *g;
BNode *h;
int vv;
scanf("%d%d",&n,&vv);
g=(Goods*)malloc(sizeof(Goods)*n);
for(i=0;i<n;i++){
scanf("%d",&v);
g[i].gno=i+1;
g[i].v=v;
}
ShellSort(g,n);
Print(g,n);
printf("\n\n");
h=CreateBox(g,n,vv);
PrintBox(h);
return 0;
}