解题思路
当j-w[i]>=0时 f[i][j]=max(f[i-1][j] , v[i]+f[i-1][j-w[i])
当j-w[i]<0时 f[i][j]=f[i-1][j]
通过公式建立动态规划表
用回溯法求最优解
思路
0—1背包类问题:有N件物品和一个容量为V的背包。第i件物品的价格(即体积,下同)是w[i],价值是c[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
相当于用a[i][j]表示前i个背包装入容量为v的背包中所可以获得的最大价值。
对于一个物品,只有两种情况
一: 第i件不放进去,这时所得价值为:a[i-1][v]
二: 第i件放进去,这时所得价值为:a[i-1][v-c[i]]+w[i]
状态转移方程为:a[i][v] = max(a[i-1][v], a[i-1][v-w[i]]+c[i])
代码如下:
#include <iostream>
using namespace std;
int main(int argc, char** argv) {
int s,n;//s为可利用钱,n为产品数
while(cin>>s>>n){
int w[1000]={0},v[1000]={0},a[100][100]={0},c[101]={0},k=1,i,j;
for(i=1;i<=n;i++){
cin>>w[i]>>v[i];
}
for(i=1;i<=n;i++){
for(j=1;j<=s;j++){
if(j-w[i]>=0){
if(a[i-1][j]>=(a[i-1][j-w[i]]+v[i])){
a[i][j]=a[i-1][j];
}else{
a[i][j]=a[i-1][j-w[i]]+v[i];
}
}else{
a[i][j]=a[i-1][j];
}
}
}
if(a[n][s]!=0){
cout<<a[n][s]<<endl;
for(i=n,j=s;i>=1&&j>=1;){
if(a[i][j]>a[i-1][j]){
c[k]=i;
k++;
j=j-w[i];
i--;
}else{
i--;
}
}
for(i=100;i>=0;i--){
if(c[i]>0){
cout<<c[i];
if(i!=1){
cout<<" ";
}
}
}
}else{
cout<<" "<<endl;
}
}
return 0;
}
以上为所有题解,希望对大家有帮助。