简单背包 输入一个物体数n,再输入n组数据,物体重量和背包价值,最后输入背包容量
4
2 3
1 2
3 4
2 2
5
方法一
先用了一个递归,会有重复问题,所以用了一个dp去储存来减低循环数目;
#include <iostream>
using namespace std;
const int maxn=1000+5;
int n,m;
int dp[maxn][maxn];
int w[maxn],v[maxn];
int res(int i,int j)
{
if(dp[i][j]!=0)
return dp[i][j];
int ans=0;
if(i==n)
ans=0;
else if(j<w[i])
{ ans=res(i+1,j);
}
else if(j>=w[i])
{
ans=max(res(i+1,j-w[i])+v[i],res(i+1,j));
}
return dp[i][j]=ans;
}
void solve()
{
int are=res(0,m);
cout<<are<<endl;
}
int main()
{
cin>>n;
cin>>m;
for(int i=0;i<n;i++)
cin>>w[i]>>v[i];
solve();
return 0;
}
但是这道题也可以用一个二重循环来解决,根据之前递归的规律
#include <iostream>
using namespace std;
const int maxn=1000+5;
int n,m;
int dp[maxn][maxn];
int w[maxn],v[maxn];
int main()
{
cin>>n;
cin>>m;
for(int i=0;i<n;i++)
cin>>w[i]>>v[i];
for(int i=n-1;i>=0;i--)
{
for(int j=0;j<=m;j++)
{
if(j<w[i])
dp[i][j]=dp[i+1][j];
else
dp[i][j]=max(dp[i+1][j],dp[i+1][j-w[i]]+v[i]);
}
}
cout<<dp[0][m];
return 0;
}
//核心代码部分可以进行改变,不过思路确实不一样的,上部分是这样的一个思路,从第 i 个 背包开始挑选,总重小于 j 时,总价值的最大值
而下面这是则是,从前0到 i 这 i+1个背包中选出总质量不超过 j 时价值的最大值
for(int i=0;i<n;i++)
for(int j=0;j<=m;j++)
{
if(j<w[i])
dp[i+1][j]=dp[i][j];
else
dp[i+1][j]=max(dp[i][j],dp[i][j-w[i]]+v[i]);
}
cout<<dp[n][m];
但是在poj上一题( 点击打开链接)单纯抄这个模板代码是会超时,超内存的
。。。而你需要做的,,很简单
把这个二维数组换成一维的,然后。。。扩大数组内存就好了
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=12880+5;
int v[maxn];
int w[maxn];
int dp[maxn];
int n,m;
int main()
{
while(cin>>n>>m)
{
for(int i=0; i<n; i++)
cin>>w[i]>>v[i];
memset(dp,0,sizeof(dp));
for(int i=0; i<n; i++)
{
for(int j=m; j>=w[i]; j--)//注意此处
{
dp[j]=max(dp[j],dp[j-w[i]]+v[i]);
}
}
cout<<dp[m]<<endl;
}
return 0;
}
/
背包问题的一个公式如下:
f[i][v]=max{f[i-1][v],f[i-1][v-c[i]]+w[i]}
进行优化,模拟代码:
for i=1..N for v=V..0 f[v]=max{f[v],f[v-c[i]]+w[i]};
最后插入一个感觉不错的背包网址 点击打开链接
现在再看这个背包问题的是一道背包入门题,2017.3.21