擅长pascal程序的高手、菜鸟(管他什么的)进来看看(要加分)

来源:百度知道 编辑:UC知道 时间:2024/05/11 16:33:28
题四 装箱问题(30分)
问题描述
有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30=,每个物品有一个体积(正整数)。

要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

样例

输入:

24 一个整数,表示箱子容量

6 一个整数,表示有n个物品

8 接下来n行,分别表示这n 个物品的各自体积

3

12

7

9

7

输出:

0 一个整数,表示箱子剩余空间。

大家加油哦!希望能附上程序,我的分并不少哦!到时候追加分数。

这个是背包问题~~我来回答
如果按照物品序号依次考虑装箱顺序的话,则问题具有明显的阶段特征。问题是当前阶段的剩余空间最小,并不意味下一阶段的剩余空间也一定最小,即该问题并不具备最优子结构的特征。但如果将装箱的体积作为状态的话,则阶段间的状态转移关系顺其自然,可使得最优化问题变为判定性问题。设状态转移方程
f[i,j]——在前i个物品中选择若干个物品(必须包括物品i)装箱,其体积正好为j的标志。显然f[i,j]=f[i-1,j-box[i]],即物品i装入箱子后的体积正好为j的前提是f[i-1,j-box[i]]=true。初始时,f[0,0]=true(1≤i≤n,box[i]≤j≤v)。
由f[i,j]=f[i-1,j-box[i]]可以看出,当前阶段的状态转移方程仅与上一阶段的状态转移方程攸关。因此设f0为i-1阶段的状态转移方程,f1为i阶段的状态转移方程,这样可以将二维数组简化成一维数组。我们按照下述方法计算状态转移方程f1:
fillchar(f0, sizeof(f0),0); {装箱前,状态转移方程初始化}
f0[0]←true;
for i←1 to n do {阶段i:按照物品数递增的顺序考虑装箱情况}
begin
f1←f0; {i阶段的状态转移方程初始化}
for j←box[i] to v do {状态j:枚举所有可能的装箱体积}
if f0[j-box[i]] then f1[j]←true;{若物品i装入箱子后的体积正好为j,则物品i装入箱子}
f0←f1; {记下当前装箱情况}
end;{for}

经过上述运算,最优化问题转化为判定性问题。再借用动态程序设计的思想,计算装箱的最大体积 k= 。显然最小剩余空间为v-k:
for i←v downto 0 do {按照递减顺序枚举所有可能的体积}