c语言,输入箱子的容量和n个物品的体积,取其中的i个物品放入箱子使箱子剩余的体积最小,求最优解

作者&投稿:咎彭 (若有异议请与网页底部的电邮联系)
C语言 动态规划 完全装箱问题~

【问题】 装箱问题
  问题描述:装箱问题可简述如下:设有编号为0、1、…、n-1的n种物品,体积分别为v0、v1、…、vn-1。将这n种物品装到容量都为V的若干箱子里。约定这n种物品的体积均不超过V,即对于0≤i<n,有0<vi≤V。不同的装箱方案所需要的箱子数目可能不同。装箱问题要求使装尽这n种物品的箱子数要少。
   若考察将n种物品的集合分划成n个或小于n个物品的所有子集,最优解就可以找到。但所有可能划分的总数太大。对适当大的n,找出所有可能的划分要花费的时间是无法承受的。为此,对装箱问题采用非常简单的近似算法,即贪婪法。该算法依次将物品放到它第一个能放进去的箱子中,该算法虽不能保证找到最优解,但还是能找到非常好的解。不失一般性,设n件物品的体积是按从大到小排好序的,即有v0≥v1≥…≥vn-1。如不满足上述要求,只要先对这n件物品按它们的体积从大到小排序,然后按排序结果对物品重新编号即可。装箱算法简单描述如下:
  { 输入箱子的容积;
   输入物品种数n;
   按体积从大到小顺序,输入各物品的体积;
   预置已用箱子链为空;
   预置已用箱子计数器box_count为0;
   for (i=0;i   { 从已用的第一只箱子开始顺序寻找能放入物品i 的箱子j;
   if (已用箱子都不能再放物品i)
   { 另用一个箱子,并将物品i放入该箱子;
   box_count++;
   }
   else
   将物品i放入箱子j;
   }
  }
   上述算法能求出需要的箱子数box_count,并能求出各箱子所装物品。下面的例子说明该算法不一定能找到最优解,设有6种物品,它们的体积分别为:60、45、35、20、20和20单位体积,箱子的容积为100个单位体积。按上述算法计算,需三只箱子,各箱子所装物品分别为:第一只箱子装物品1、3;第二只箱子装物品2、4、5;第三只箱子装物品6。而最优解为两只箱子,分别装物品1、4、5和2、3、6。

   若每只箱子所装物品用链表来表示,链表首结点指针存于一个结构中,结构记录尚剩余的空间量和该箱子所装物品链表的首指针。另将全部箱子的信息也构成链表。以下是按以上算法编写的程序。
  【程序】
  # include
  # include
  typedef struct ele
  { int vno;
   struct ele *link;
  } ELE;
  typedef struct hnode
  { int remainder;
   ELE *head;
   Struct hnode *next;
  } HNODE;
  
  void main()
  { int n, i, box_count, box_volume, *a;
   HNODE *box_h, *box_t, *j;
   ELE *p, *q;
   Printf(“输入箱子容积
”);
   Scanf(“%d”,&box_volume);
   Printf(“输入物品种数
”);
   Scanf(“%d”,&n);
   A=(int *)malloc(sizeof(int)*n);
   Printf(“请按体积从大到小顺序输入各物品的体积:”);
   For (i=0;i   Box_h=box_t=NULL;
   Box_count=0;
   For (i=0;i   { p=(ELE *)malloc(sizeof(ELE));
   p->vno=i;
   for (j=box_h;j!=NULL;j=j->next)
   if (j->remainder>=a[i]) break;
   if (j==NULL)
   { j=(HNODE *)malloc(sizeof(HNODE));
   j->remainder=box_volume-a[i];
   j->head=NULL;
   if (box_h==NULL) box_h=box_t=j;
   else box_t=boix_t->next=j;
   j->next=NULL;
   box_count++;
   }
   else j->remainder-=a[i];
   for (q=j->next;q!=NULL&&q->link!=NULL;q=q->link);
   if (q==NULL)
   { p->link=j->head;
   j->head=p;
   }
   else
   { p->link=NULL;
   q->link=p;
   }
   }
   printf(“共使用了%d只箱子”,box_count);
   printf(“各箱子装物品情况如下:”);
   for (j=box_h,i=1;j!=NULL;j=j->next,i++)
   { printf(“第%2d只箱子,还剩余容积%4d,所装物品有;
”,I,j->remainder);
   for (p=j->head;p!=NULL;p=p->link)
   printf(“%4d”,p->vno+1);
   printf(“
”);
   }
  }

你用这个代码求出了最大体积
再用一个函数求出所有符合这个最大体积的组合就可以了
既然这是你自己的代码,想必你是会写的
望采纳

//不可以用贪心,贪心不能保证最优解
//刚写的code,用的动态规划,测试通过,如果有疑问,欢迎交流
#include<stdio.h>
#include<stdlib.h>
void print_path_r(int *pre_path, int j){//正序输出
if(pre_path[j] == j){
printf("%d ", j+1);
}else{
print_path_r(pre_path, pre_path[j]);
printf("%d ", j+1);
}
}
void print_path(int *pre_path, int num,int *dp){
int i,j;
for(i = 0; i<num; i++){
if(dp[i] == 0){
//j = i;//倒序输出
//while(j!=pre_path[j]){
// printf("%d ", j+1);
// j = pre_path[j];
//}
//printf("%d ", j+1);
print_path_r(pre_path, i);
printf("
");
}
}
}
int main(){
int *dp;
int *weights;
int *pre_idx;
int num;
int sum_v,cur_min;
int i,j;
scanf("%d", &sum_v);
scanf("%d", &num);

dp = (int *) malloc(sizeof(int)*num);
weights = (int*)malloc(sizeof(int)*num);
pre_idx = (int *) malloc(sizeof(int)*num);
for(i = 0; i<num;i++){
scanf("%d", &weights[i]);
dp[i] = sum_v - weights[i];
pre_idx[i] = i;
}
for(i = 1; i<num; i++){
cur_min = dp[i];
for(j =0;j <i; j++){
if(dp[j] - weights[i]>=0&&(dp[j] - weights[i]<cur_min)){
cur_min = dp[j] - weights[i];
pre_idx[i] = j;
}
}
dp[i] = cur_min;
}
print_path(pre_idx, num, dp);
free(weights);
free(pre_idx);
free(dp);
return 0;
}



平方面积,总平方面积-个体平方面积相加求余值最大。排除平方面积相加值大于总平方面积值
变量,符集

用贪心法不能解决,得用动态规划法或回溯法。

典型的背包问题 应该使用动态规划


c语言,输入箱子的容量和n个物品的体积,取其中的i个物品放入箱子使箱子...
j+1);}}void print_path(int *pre_path, int num,int *dp){int i,j;for(i = 0; i<num; i++){if(dp[i] == 0){\/\/j = i;\/\/倒序输出\/\/while(j!=pre_path[j])

装箱问题
有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30,每个物品有一个体积(正整数)。要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。样例 输入:24 一个整数,表示箱子容量 6 一个整数,表示有n个物品 8 接下来n行,分别表示这n 个物品...

C语言 动态规划 完全装箱问题
{ 输入箱子的容积;输入物品种数n;按体积从大到小顺序,输入各物品的体积;预置已用箱子链为空;预置已用箱子计数器box_count为0;for (i=0;i { 从已用的第一只箱子开始顺序寻找能放入物品i 的箱子j;if (已用箱子都不能再放物品i){ 另用一个箱子,并将物品i放入该箱子;box_count++;...

C语言,算法、动态规划:有一个箱子的容量为v(正整数,0<=v<=20000),同 ...
define N 30 int xiangzi(int n ,int V ,int a[]) \/\/楼主后面的Vo数组必须放进递归函数里面或定义成全局数组 另外h[n]什么情况??{ int minv,t,m=V;if(n==0){ if(a[n]<=V) \/\/ V是剩余空间。minv是所生最小空间,是待求变量,而不是已知的 ,不能V<minv 这样用来...

C语言中f=f*n表示什么意思
{ 输入箱子的容积; 输入物品种数n; 按体积从大到小顺序,输入各物品的体积; 预置已用箱子链为空; 预置已用箱子计数器box_count为0; for (i=0;i<n;i++) { 从已用的第一只箱子开始顺序寻找能放入物品i 的箱子j; if (已用箱子都不能再放物品i) { 另用一个箱子,并将物品i放入该箱子; box_count...

我的世界怎么用命令方块复制箱子里的物品?(手机版)
在弹出的界面中输入以下命令:\/clonex1y1z1x2y2z2xyz,其中xyz1是源方块的坐标,xyz2是源方块的对角线上的第二个坐标,x、y、z是目标方块的坐标。3、在语言栏内输入后,按输入法上的回车键即可不过应该手机版不能直接输入指令,你可以在我的世界盒子里装一个指令插件指令大全。

输入3个分别表示箱子长,宽,高的整数值,判断并输出该箱子是正方体还是长...
,&l,&w,&h);if(l==w==h)printf("该箱子是正方体。\\n");else printf("该箱子是长方体。\\n");return 0;} 问题分析:在输入if语句中的判断条件时,我输入的是“l=w=h”,运行报错了,数学运算符=与C语言中的赋值符号是不能窜通的,正确的是“l==w==h”时,运行成功了。

c语言编程 装箱子
i++)scanf("%d",&a[i]);for(j=1;j<=100;j++)b[j]=100;for(i=1;i<=x;i++)for(j=1;j<=100;j++){ if(b[j]-a[i]>=0){ printf("%d %d\\n",a[i],j);b[j]=b[j]-a[i];if(max<j)max=j;break;} } printf("所需的箱子数目为%d\\n",max);return 0;} ...

c语言。。求解!!!
详情请查看视频回答

我的世界怎么把箱子锁起来
1、要给箱子上锁,需要使用到牌子,并且在上面打上[private](意思为私有的名称),打上这个英文,就是表示箱子是自己的,然后就是自己的ID地址,这样箱子就除了自己其他人就无法打开。2、想给自己的好友也权限打开,那就需要设置一下,右键点击牌子,然后在上面输入\/lockette,和行数,好友ID,比如,...

肇东市13116947332: 装箱问题 -
类苛妇炎: 有一个箱子容量为V(正整数,0 要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小.样例输入:24 一个整数,表示箱子容量6 一个整数,表示有n个物品8 接下来n行,分别表示这n 个物品的各自体积312797输出:0 ...

肇东市13116947332: 程序有问题了(C语言,非C++)!!
类苛妇炎: 啊..给你个标程吧.我自己编的. #include<stdio.h> int f[31][20001],w[31]; int main() { int i,j,k,n,l=0; freopen("packing.in","r",stdin); freopen("packing.out","w",stdout); scanf("%d%d",&k,&n); for(i=1;i<=n;i++){scanf("%d",&j);if(j<=k)...

肇东市13116947332: 装箱子的C语言程序
类苛妇炎: 如有需要,可以看看这里. http://hi.baidu.com/yanggq/blog/item/b6b7c3131cc01b28dd5401c1.html

肇东市13116947332: c语言0 - 1背包问题高手进来 -
类苛妇炎: #include "stdio.h"#include "time.h"#define BOXMAX 10 typedef struct BOX { int locate[BOXMAX]; float weight[BOXMAX]; float price[BOXMAX]; int n; }box; void main() { box bx; int sign=0; int row,line; int maxbox; int tmp; float maxvalue=0; int b...

肇东市13116947332: C语言 输入n表示输入的数字个数,输出输入的n个数的总和 -
类苛妇炎: #include <stdio.h> int main(){ int i,n,num,s=0; scanf("%d",&n); for(i=0;i<n;i++){ scanf("%d",&num); s+=num; } printf("%d",s); return 0; }//运行示例:

肇东市13116947332: 什么叫winner tree -
类苛妇炎: 这叫做赢者树,是竞赛树中的一个,还有一个输者树.1.基本东西: 形象来说,外部节点表示选手捉对厮杀,内部节点表示比赛的胜者(败者).定义如下:对于n名选手,赢者树是一棵含n个外部节点,n-1个内部节点的完全二叉树,其中每个内...

肇东市13116947332: 完全背包问题,用C语言编译的代码~是所有代码,不是一段关键代码. -
类苛妇炎: 参考代码: /** n:物品种类 每种只能选取一种* capacity:背包容量* c[i]:第i种物品的花费 cost* v[i]:第i种物品的价值 value* f[j]:i状态下容量为j时背包可获得的最大价值*/ int getMaxValue(int n,int capacity){for(int i=0;i<n;i++)for(int j=...

肇东市13116947332: c语言编程序 -
类苛妇炎: }2 第二个题目太笼统了;, m * n / n_cup); } else printf(");n"; return 0; n_cup = n; res = m_cup % n_cup; /Greatest common divisor,而且也不难;Error;Lease common multiple : %d\n&quot,也没有说明数据删除查找是按照值还是按照下标;...

肇东市13116947332: C语言怎么实现未知的输入物品名称和输入物品数量的录入,然后输入一个结束物品名称和输入物品数量的录入 -
类苛妇炎: 如果只想算出总金额 while循环就够了 如果连每种的名称 价格都要记录的话 那么链表是首选

肇东市13116947332: 求计算背包问题总方案数的C语言程序或者思路啊!!!!! -
类苛妇炎: #include<stdio.h>#define N 100 int str[N]; int w[N]; int k=0; void backtrack(int i,int n,int m) { if(m==0){ k++; for(int i=1;i<=n;i++) if(str[i]!=i) printf("%d ",i); printf("\n"); } if(i<=n&&m>0){ for(int j=0;j*w[i]<=m;j++){ if(j!=0)str[i]=0; backtrack(i+1,n,m-j*w[i]);...

本站内容来自于网友发表,不代表本站立场,仅表示其个人看法,不对其真实性、正确性、有效性作任何的担保
相关事宜请发邮件给我们
© 星空见康网