给定n(n<=100)种物品和一个背包。物品i的重量是wi,价值为vi,背包的容量为C(C<=1000)。问:应如何选择装入背包中的物品,使得装入背包中物品的总价值最大? 在选择装入背包的物品时,对每种物品i只有两个选择:装入或不装入。不能将物品i装入多次,也不能只装入部分物品i。
输入格式:
共有n+1行输入: 第一行为n值和c值,表示n件物品和背包容量c; 接下来的n行,每行有两个数据,分别表示第i(1≤i≤n)件物品的重量和价值。
输出格式:
输出装入背包中物品的最大总价值。
输入样例:
在这里给出一组输入。例如:
5 10
2 6
2 3
6 5
5 4
4 6
输出样例:
在这里给出相应的输出。例如:
15
回溯
#include<iostream>
#include<algorithm>
using namespace std;
int n;//物品种类
int c;//背包容量
double w[101];//物品重量
double v[101];//物品价值
double a[101];//单位
float cp=0.0;//当前价值
float cw=0.0;//当前重量
float bestp=0;//当前最优价值
int i,j;
int bound(int t){
int q=c-cw;//当前剩余重量
int b=cp;//当前价值
while(t<=n&&w[t]<=q){
q=q-w[t];
b=b+v[t];
t++;
}
if(t<=n){
b=b+q*a[t];
}
return b;
}
void Knapsack(){
for(i=0;i<n;i++){
for(j=0;j<n-i-1;j++){
if(a[j]<a[j+1]){
swap(a[j],a[j+1]);
swap(w[j],w[j+1]);
swap(v[j],v[j+1]);
}
}
}
//for(i=0;i<n;i++){
// cout<<a[i]<<" "<<w[i]<<" "<<v[i]<<endl;
//}
}
void Backtrack(int t){
if(t>n){
bestp=cp;
// cout<<"bestp="<<bestp<<endl;
return;
}
if(w[t]+cw<=c){
cw=cw+w[t];
cp=cp+v[t];
// cout<<cp<<endl;
Backtrack(t+1);
cw=cw-w[t];
cp=cp-v[t];
}
if(bound(t+1)>bestp){
Backtrack(t+1);
}
}
int main(){
cin>>n>>c;
for(i=0;i<n;i++){
cin>>w[i]>>v[i];
a[i]=v[i]/w[i];
}
Knapsack();
Backtrack(0);
cout<<bestp;
}
动态规划算法
#include<iostream>
using namespace std;
int n;//n种物品
int w[200];//存放物品重量
int v[200];// 物品价值
int c;//背包容量
int m[200][200];
int main(){
cin>>n>>c;
int i,j;
for(i=0;i<n;i++){
cin>>w[i]>>v[i];
}
for(i=n-1;i>=0;i--){
for(j=0;j<=c;j++){
if(j>=w[i]){//可以装的进去
m[i][j]=max(m[i+1][j],m[i+1][j-w[i]]+v[i]);
}
else{
m[i][j]=m[i+1][j];
}
}
}
cout<<m[0][c];
}