完全背包问题
实例:n=4,b=10
v1=1, v2=3, v3=5, v4=9
w1=2, w2=3, w3=4, w4=7
n是背包的种类,b是书包的总重量
//安利北京大学mooc 此算法是老师所讲算法的一个实现
//https://www.icourse163.org/learn/PKU-1002525003#/learn/content?type=detail&id=1003850904&cid=1004665219
#include<iostream>
#include<algorithm>
using namespace std;
const int N=4;
const int B=10;
const int v[4]={1,3,5,9};
const int w[4]={2,3,4,7};
int f[100][100];
//标记函数
int ii[100][100];
int main(){
//建模
//先进行数据的初始化
for(int i=0;i<=B;i++){
f[0][i]=0;
}
for(int i=0;i<=N;i++){
f[i][0]=0;
}
for(int i=1;i<=B;i++){
int a =(i/w[0]);
cout<<a<<'\n';
f[1][i]=a*v[0];
}
//
//标记数组的操作,下同
for(int i=1;i<=B;i++){
if(i>=w[0]){
ii[1][i]=1;
}
}
/
//开始正式的动态规划
for(int k=2;k<=N;k++){
for(int y=1;y<=B;y++){
if(y-w[k-1]>=0){
f[k][y]= max(f[k-1][y],f[k][y-w[k-1]]+v[k-1]);
/
if(f[k-1][y]>f[k][y-w[k-1]]+v[k-1]){
ii[k][y]=ii[k-1][y];
}else{
ii[k][y]=k;
}
/
}else{
f[k][y]= f[k-1][y];
///
ii[k][y]=ii[k-1][y];
///
}
}
}
//打印数组
for(int i=1;i<=N;i++){
for(int j=1;j<=B;j++){
cout<<f[i][j]<<' ';
}
cout<<endl;
}
for(int i=1;i<=N;i++){
for(int j=1;j<=B;j++){
cout<<ii[i][j]<<' ';
}
cout<<endl;
}
//对数数组进行逆向求解
int x[100];
for(int i=1;i<=N;i++){
x[i]=0;
}
int y=B,k=N;
while(ii[k][y]!=k){
k=k-1;
}
do{
k=ii[k][y];
x[k]=1;
y=y-w[k-1];
while(ii[k][y]==k){
y=y-w[k-1];
x[k]=x[k]+1;
}
}while(ii[k][y]!=0);
for(int i=1;i<=N;i++){
cout<<x[i]<<'\t';
}
return 0;
}