(⊙o⊙)…,不打算发的,因为思路就是将多重背包转成0-1背包解决。比较水。
就是0-1背包的代码简化了不少~按照课本讲的代码方式去写确实很坑……
//x[i]是物品i的个数,a[i],c[i]依次为质量,价值,容量为n
然后这次处理和上一个的区别就是dp[i][j]代表的意义略有不同,汗,其实也是一个意思
此处dp[i][j]代表,容量为j,物品从1->i物品获得的最优解
for(i =1; i < m+1 ;i++)
for(j =1 ;j<n+1;j++)
{
if(w[i]<=j) //如果当前物品的容量小于背包容量
dp[i][j]=max( v[i] + dp[i-1][j -w[i]]
,
dp
[
i
-
1
][
j
]);
else
dp
[
i
][
j
]
=
dp
[
i
-
1
][
j
];
}
完整代码:
//x[i]是物品i的个数,a[i],c[i]依次为质量,价值,容量为n
//思路就是转换成0-1背包处理
#include<iostream>
using namespace std;
const int MAX = 9999;
int main()
{
int n;
// 背包容量为n
int
i
,
j;
int
m
=
0;
//物品个数
cout
<<
"请输入背包的容量n:";
cin
>>n;
int
x
[
MAX
]
=
{
0
};
//个数
int
a
[
MAX
]
=
{
0
};
//质量
int
c
[
MAX
]
=
{
0
};
//价值
int
w
[
MAX
]
=
{
0
};
//转换成0-1背包后的质量
int
v
[
MAX
]
=
{
0
};
//装成0-1背包后的价值
cout
<<
"请分别输入物品的个数,该物品的质量和价值(中间用空格隔开,输入个数为0时结束):"
<<
endl;
//当x[i] = 0时结束
for(
i
=
1 ;
cin
>>
x
[
i
]
&&
x
[
i
]
!=
0 ;
i
++)
{
cin
>>
a
[
i
]
>>
c
[
i
];
for(
j
=
m
+
1;
j
<=
m
+
x
[
i
] ;
j
++)
{
w
[
j
]
=
a
[
i
];
v
[
j
]
=
c
[
i
];
}
m
+=
x
[
i
];
//最后得到m就是物品的个数
}
int
temp
=
i
-
1;
//多输入了一个0,不用计入
int
**
dp
=
new
int
*
[
m
+
1
];
for(
i
=
0;
i
<
m
+
1 ;
i
++)
dp
[
i
]
=
new
int
[n
+
1
];
//dp[m+1][n+1]
//dp[i][j]容量为j时,1->i中的物品的最优值
for(
i
=
0;
i
<=
m;
i
++)
for(
j
=
0;
j
<=n;
j
++)
dp
[
i
][
j
]
=
0;
for(
i
=
1;
i
<
m
+
1 ;
i
++)
for(
j
=
1 ;
j
<n
+
1;
j
++)
{
if(
w
[
i
]
<=
j)
//如果当前物品的容量小于背包容量
dp
[
i
][
j
]
=(
v
[
i
]
+
dp
[
i
-
1
][
j
-
w
[
i
]]
>
dp
[
i
-
1
][
j
] )
?(
v
[
i
]
+
dp
[
i
-
1
][
j
-
w
[
i
]] )
:
dp
[
i
-
1
][
j
];
else
dp
[
i
][
j
]
=
dp
[
i
-
1
][
j
];
}
cout
<<
"能放入的最大价值为"
<<
dp
[
m
][n
]
<<
endl;
//用于判断哪些物品装入了
int
judge
[
MAX
]
=
{
0
} ;
for(
i
=
m ;
i
>
1;
i
-- )
if(
dp
[
i
][n
]
==
dp
[
i
-
1
][n
])
judge
[
i
]
=
0;
else
{
judge
[
i
]
=
1; n
-=
w
[
i
];
}
judge
[
1
]
= (
dp
[
1
][n
])
?
1
:
0;
int
temp_w
[
MAX
]
=
{
0
};
int
temp_v
[
MAX
]
=
{
0
};
int
times
[
MAX
]
=
{
0
};
int
k
=
1;
for(
i
=
1;
i
<
m
+
1;
i
++)
{
if(
judge
[
i
]
==
1
){
temp_w
[
k
]
=
w
[
i
];
temp_v
[
k
]
=
v
[
i
];
k
++
;}
}
int
k_max
=
k;
for(
i
=
1;
i
<=
temp ;
i
++)
{
for(
k
=
0;
k
<=
k_max;
k
++)
if(
temp_w
[
k
]
==
a
[
i
]
&&
temp_v
[
k
]
==
c
[
i
]){
times
[
i
]
++
;}
}
cout
<<
"可以装入的物品编号,装入该物品个数,该物品的质量和价值分别是:"
<<
endl;
for(
i
=
1;
i
<=
temp;
i
++)
if(
times
[
i
]
>
0)
cout
<<
"第"
<<
i
<<
"个物品:"
<<
times
[
i
]
<<
"个 "
<<
a
[
i
]
<<
" "
<<
c
[
i
]
<<
endl;
}
//思路就是转换成0-1背包处理
#include<iostream>
using namespace std;
const int MAX = 9999;
int main()
{
}
测试数据
30
3 4 5
2 6 4
1 3 4
4 5 8
0
10
1 2 6
1 2 3
1 6 5
1 5 4
1 4 6
0