背包问题c 语言程序,0-1背包问题c语言程序-20210412070525.docx-原创力文档

0-1背包问题

问题描述

给定n种物品和一背包,物品i的重量是wi,其价值是pi,背包的容量是如何选择 装入背包中的物品总价值最大?

问题分析

记c[iJW表示前i个物品,在背包容量大小为m的情况下,最大的装载

Mo

如果不放第i件物品,那么问题就转化为前I件物品放入容量为m的背

包中”价值为如果放第i件物品,那么问题就转化为前I件物品

放入剩下的容量为的背包中”此时能获得的最大价值就是再加上 通 过放入第i件物品获得的价值p[ilo因为背包最大容量M未知。所以,我们的程序要从 1到M—个一个的试。比如,开始任选N件物品的一个。看对

应M的背包,能不能放进去,如果能放进去,并且还有多的空间,则多出來的空间里 能放N-1物品中的最大价值。从以上最大价值的构造过程中可以看出:

c (n, m) =max{c (n-l , m), c (n~l , m-w[n])+p (n)

其中c[i-l] [m]表不第i件物品不装入背包中,而c[i-l] [m-w[i]]+p[i]表不第i件 物 品 装入背包中。

伪代码:

1 ?最优彳宜 max(xl *pl +x2*p2+,, xn*pn)

int knapsack(int m, int n,int *w, int *p) bool a;

for(int i二1 ;i<=n;i++)

for(int j二1 ;j<=m;j++)

{a=p[i]+c[i-l] [j-w[i]]>c[i J ] [j] ;c[i] [j]=a?p[i]+c[i-l]:c[i ? 1] [j];

〃前者表示放i物品,后者表示不放i物品

)

else //i号物品重量大于剩余容量,不能再放i号物品c[i]D] =c[i-l]OJ;

)

return(c[n] [m]) ;//最后的值即为最优值,返回主函数

)

2?求最优 n 7L 0-1 向量(xl ,x2,x3553xn)

int getbest(int m, int n, int *w, int *p)

if (n==0)retuin 0;//递归,每次递归 n 减 1, n 为 0 时退岀 if (w[n]>m)

<

x[n]=0;

getbest (m, n-l5w, p);

else

3 & p n H31*

-muw*淫

妥巨〉

今 cludecss i o ? hv

吵 R boo -

yapsack (inf m

旷f * p

00 - a

吵前m w〉裆毬血

M5k、、x 選弗咄

w inf

n5-f *

if (w[i]<=j)

{a二讥i]+c[i-l] [j-w[i]]>c[i-l] [j] ;c[i] [j]=a?p[i]+c[i-l]:c[i-l] [j];

〃前者表示放i物品,后者表示不放i物品

)

else //i号物品重量大于剩余容量,不能再放i号物品

}

return(c[n] [m]);〃最后的值即为最优值,返回主函数

)

〃求最优n元0-1向量(xl, x2, x3……,xn)

int getbest (int mjnt n,int *w, int *p)

{

if(n==O)retuin 0;//递归,每次递归 n 减 1, n 为。时退出 if(w[n]>m)

<

x[n]=0;

getbest (m, n-1, w, p);

)

else

{

〃如果 c[n] [m]由 p[n] +c[n-1] [m-w[n]]而来,则 x[n]二 1;

〃女 口果 c[n] [m]由 c[n-l] [mJ]而来贝 S x[n]=0;

[n]=c[n-l ] [m]〈二p[n]+c [n-l ] Lm-w[n]];

if (x.nl)

getbest(m-wEn], n~l , w, p);

else getbest (m, n-1, w, p);

)

)

void mainO

int m, n;

int 佔NULL;

int *p=NULL;

printfC输入背包容量和货物个数「);

scanf (n%d%d'' ;&m, &n);

P=(int *)calloc(n, sizeof (int)) ; n 分配 n*sizeof (int)的内存大小,存取 n 个物品的 价 格w=(int *)calloc(n, sizeof (int)) ; n分酉己n*sizeof (int)的内存大小,存取n个物品 的质 量if(!p|| !w)//检测分配是否成功

printf ("Not Enough Memory! \nk);

exit ⑴;//分配失败,退出

for(int i二1 ;i

printf (M 物品 x%d 的重量和价值i) ; scanf (a%d%d^, w+i5p+i);

pri

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值