#### 【物品无限的背包问题】: n种物品,每种均有无穷个,第i种物品的体积为v[i],价值为w[i],装C容量的背包,不超过C的情况下价值最多为?
输入:
3 3
1 2
3 1
2 2
输出:
6
//无限背包问题【递推法】
#include
#include
#define maxn 1010
#define maxv 10010
int n, C, v[maxn], w[maxn], f[maxv];
int main(){
scanf("%d%d", &C, &n);
for (int i = 1; i <= n; ++i)
scanf("%d%d", v+i, w+i);
memset(f, 0, sizeof(f));
for(int i = 1; i <= C; ++i) //以C=1开始枚举每一个物品的价值
for(int j = 1; j <= n; ++j)//第j个物品可以有多个
if(i >= v[j] && f[i-v[j]] + w[j] > f[i])
//当i阶段时大于第j个物品的体积即有能力拿时,并且拿后的价值大于不拿再执行
f[i] = f[i-v[j]] + w[j];
printf("%d\n", f[C]);
return 0;
}
//无限背包问题【记忆搜索法】
#include
#include
#define maxn 1010
#define maxv 10010
int n, C, v[maxn], w[maxn], f[maxv];
int dp(int C)
{
if(f[C]!=0)
return f[C];
for(int j = 1; j <= n; ++j)
if(C >= v[j] && f[C-v[j]] + w[j] > f[C])
f[C] = dp(C-v[j]) + w[j];
return f[C];
}
int main(){
scanf("%d%d", &C, &n);
for (int i = 1; i <= n; ++i)
scanf("%d%d", v+i, w+i);
memset(f, 0, sizeof(f));
dp(C);
printf("%d\n", dp(C));
return 0;
}
;
;
;
;
;
//0-1背包问题【递归法】
#include
#include
#define maxv 10010
#define maxn 110
int n, C, w[maxn], v[maxn], f[maxn][maxv];
int main(){
scanf("%d%d", &C, &n);
for(int i = 1; i <= n; ++i)
scanf("%d%d", v+i, w+i);
memset(f, 0, sizeof(f));
for(int i = n; i >= 1; --i) //共有n层
for(int j = 0; j <= C; ++j){
//f[i][j] = i==1 ? 0 : f[i+1][j];
f[i][j] = f[i+1][j];
if(j>=v[i] && f[i+1][j-v[i]] + w[i]>f[i][j]) f[i][j] = f[i+1][j-v[i]] + w[i];
}
printf("%d\n", f[1][C]);
return 0;
}
//0-1背包问题【记忆搜索法】
#include
#include
#define maxv 10010
#define maxn 110
int n, C, w[maxn], v[maxn], f[maxn][maxv];
int dp(int i,int j)
{
if(i>n)
return 0;//超过范围
if(f[i][j]!=0)
return f[i][j];//表示算过的数据不用算。
/*一个tips:在“固定终点的最长短路”中,例硬币问题,路径长度S可为0,所以不能用d=0表示d值没有被算过,所以初始值不可为0,应设为-1.上面可直接简化为if(f[i][j]>=0)。或者多设一个数组vis[][]*/
else
{
f[i][j]=dp(i+1,j);
if(j>=v[i] && f[i][j] < ( dp(i+1,j-v[i])+w[i] ) )
f[i][j]=dp(i+1,j-v[i])+w[i];
}
return f[i][j];
}
int main(){
scanf("%d%d", &C, &n);
for(int i = 1; i <= n; ++i) scanf("%d%d", v+i, w+i);
memset(f, 0, sizeof(f)); //
printf("%d\n", dp(1,C));
return 0;
} //上面dfs中if(n>n) return 0;if(f[i][j]!=0) return f[i][j];
//0-1背包问题【递归法】
#include
int c[100],w[100];
int f(int n, int v)
{
int max1,max2,max;
if(n==0)
return 0;
else
{
if(v1,v);
else
max2=w[n]=f(n-1,v-c[n])+w[n];
if(max1>max2)
return max1;
else
return max2;
}
}
void main(void)
{
int n,v;
int i,max;
printf("请输入背包的容量:");
scanf("%d",&v);
printf("请输入物品的个数:");
scanf("%d",&n);
for(i=1;i<=n;i++)
{
printf("请输入第%d个物品的重量和价值:",i);
scanf("%d%d",&c[i],&w[i]);
}
max=f(n,v);
printf("背包取得的最大收益为%d\n", max);
}