题目描述 已知背包总空间s 对于所给的n种物品 每种物品所占空间 w[i] 价值 p[i] 每种物品有无限多个 求在不超过背包容量的前提下 背包所能容纳物品的最大价值或者最小价值
01背包与完全背包的代码上的区别就是 循环在每个物品时 背包体积 的时候的逆序与正序
即 for i=0->n
01背包 for j=s->w[i] 完全背包 for j=w[i]->s
*对于为什么01背包逆序而完全背包正序 的问题要弄清楚
01背包由于每件物品只有一个 只存在一种情况 如果正序进行的话 会造成一件物品的重选问题导致问题的矛盾 所以一定要逆序
完全背包 一件物品可以有无限个 故当处理第 i 件物品时 dp[v-wp[i]] 仍可以参考第i件物品拿的少的情况 所以可以正序
完全背包代码如下
#include <iostream>
#include <cstdio>
#include <cstring>
using namespace std;
const int inf=99999999;
int s,e;
int N;
int dp[10005];
struct coins
{
int val;
int weight;
}data[505];
int CompletePack()
{
for(int i=1;i<=(e-s);i++)
dp[i]=inf;
dp[0]=0;
//一维 O(vn)
for(int i=1;i<=N;i++)
{
for(int j=data[i].weight;j<=(e-s);j++)
{
if(dp[j-data[i].weight]+data[i].val<dp[j])
dp[j]=dp[j-data[i].weight]+data[i].val;
}
}
return 0;
}
int main()
{
int time;
scanf("%d",&time);
while(time--)
{
scanf("%d%d%d",&s,&e,&N);
for(int i=1;i<=N;i++)
scanf("%d%d",&data[i].val,&data[i].weight);
CompletePack();
//If the weight cannot be reached exactly
if(dp[e-s]!=inf)
cout<<"The minimum amount of money in the piggy-bank is "<<dp[e-s]<<"."<<endl;
else
cout<<"This is impossible."<<endl;
/*
for(int i=0;i<=(end-start);i++)
{
if(i!=(end-start)) cout<<dp[i]<<" ";
else
cout<<dp[i]<<endl;
}
*/
}
return 0;
}
参考题目 http://acm.hdu.edu.cn/showproblem.php?pid=1114