1、
(1)、一个背包容积为T(0<=T<=2000),现在有N(0< N<=1000)个物品,每个物品有一定体积V(1<=V<=5000)。从这N个物品中选取若干个装入背包内,使背包所剩的空间最小。请求出最小的剩余空间?
(2)、若每种物品有无限个,请求出最小的剩余空间
状态:f[j]表示能否选取若干个物品放入背包中,使背包已使用的体积恰好为j,能为true,不能为false
#include<cstdio>
using namespace std;
int a[1002];
bool f[2002];
int main()
{
int t,n;
scanf("%d%d",&t,&n);
for(int i=1;i<=n;i++) scanf("%d",&a[i]);
f[0]=1;
for(int i=1;i<=n;i++)
for(int j=t;j>=a[i];j--)//一个
//for(int j=a[i];j<=t;j++)//无限个
{
if(f[j-a[i]]==1) f[j]=1;
}
for(int i=t;i>=0;i--)
{
if(f[i]==1)
{
printf("%d",t-i);
break;
}
}
}
2、
(1)、一个背包容积为T(0<=T<=2000),现在有N(0< N<=1000)个物品,每个物品有一定体积V(1<=V<=5000)。每个物品有一定价值W(1<=W<=5000)。从这N个物品中选取若干个装入背包内,使背包总价值最大。请求出最大价值。
(2)、若每种物品有无限个,请求出最大价值。
状态:f[j]表示容积为j的背包,能装下的物品的最大价值。(j不一定要恰好用完)
方程:f[j]=max(f[j],f[j-v[i]]+w[i]);
#include<cstdio>
#include<iostream>
using namespace std;
int f[2003],v[1003],w[1003];
int main()
{
int t,n;scanf("%d%d",&t,&n);
for(int i=1;i<=n;i++) scanf("%d",&v[i]);
for(int i=1;i<=n;i++) scanf("%d",&w[i]);
//初值f[0][0]=0,其它为-inf(0也无妨)
for(int i=1;i<=n;i++)
for(int j=t;j>=v[i];j--)//一个
//for(int j=v[i];j<=t;j++)//无限
{
f[j]=max(f[j],f[j-v[i]]+w[i]);
}
printf("%d",f[t]);
}
3、有两个背包,一个容积为A,一个容积为B,现在有N个物品,每个物品有一定体积V。每个物品有一定的价值W。从这N个物品中选取若干个装入背包内,使背包内物品的价值最大。请求出最大价值?
状态:f[i][j]表示第一个背包容积为i,第二个背包容积为j时,能得到的最大价值。(不一定要恰好用完)
方程:f[i][j]=max{ f[i-v[k]][j]+w[k],f[i][j-v[k]]+w[k],f[i][j]} (j>=v[k],i>=v[k])
#include<cstdio>
#include<iostream>
using namespace std;
int f[303][303],v[303],w[303];
int main()
{
int n,a,b;scanf("%d%d%d",&n,&a,&b);
for(int i=1;i<=n;i++) scanf("%d",&v[i]);
for(int i=1;i<=n;i++) scanf("%d",&w[i]);
//初值f[0][0]=0,其它为-inf(0也无妨)
for(int k=1;k<=n;k++)
for(int i=a;i>=0;i--)
for(int j=b;j>=0;j--)
{
if(i>=v[k]) f[i][j]=max(f[i][j],f[i-v[k]][j]+w[k]);
if(j>=v[k]) f[i][j]=max(f[i][j],f[i][j-v[k]]+w[k]);
}
printf("%d",f[a][b]);
}
4、
装满两个背包,且使总权值最小
http://blog.csdn.net/Y__XV/article/details/52733436