问题模板
01背包,有件物品和一个容量为V的背包。放入第
件物品耗费的费用是
,得到的价值是
。求解将哪些物品装入背包可使价值总和最大。
例题
思路
对于01背包问题中的每一种物品都有取或不取两种选择:取或不取。对于子问题定义状态:即表示前
件物品恰好放入一个容器为
的背包可以获得的最大价值。则其状态转移方程为:
源码
内存不压缩版本:
#include<iostream>
using namespace std;
#define ll long long
const int MAXN=111;
int t,m;
int a[MAXN],b[MAXN];
int f[1010][1010];
int read(){
int f=1,ans=0;
char c;
c=getchar();
while(!isdigit(c)){
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c)){
ans=ans*10+c-'0';
c=getchar();
}
return f*ans;
}
int main() {
t=read();
m=read();
for(int i=1;i<=m;i++) a[i]=read(),b[i]=read();
for(int i=1;i<=m;i++){
for(int j=t;j>=0;j--){
if(j>=a[i]){
f[i][j]=max(f[i-1][j],f[i-1][j-a[i]]+b[i]);
}else{
f[i][j]=f[i-1][j];
}
}
}
cout<<f[m][t];
return 0;
}
内存压缩版本:
#include<iostream>
using namespace std;
const int MAXN=111;
int t,m;
int a[MAXN],b[MAXN];
int f[1010];
int read(){
int f=1,ans=0;
char c;
c=getchar();
while(!isdigit(c)){
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c)){
ans=ans*10+c-'0';
c=getchar();
}
return f*ans;
}
int main() {
t=read();
m=read();
for(int i=1;i<=m;i++) a[i]=read(),b[i]=read();
for(int i=1;i<=m;i++){
for(int j=t;j>=0;j--){
if(j>=a[i]){
f[j]=max(f[j],f[j-a[i]]+b[i]);
}
}
}
cout<<f[t];
return 0;
}