##背包的学习
一、01背包(每种物品最多可放一次)
样题:有N件物品和一个容量为V的背包。第i件物品的费用是w[i],价值是v[i]。求解将哪些物品装入背包可使价值总和最大。
*一维数组:f[j]表示容量为j的背包可以获得的最大价值

例题:http://acm.hdu.edu.cn/showproblem.php?pid=2602
代码如下:
#include<stdio.h>
#include<string.h>
#define m 1009
int max( int a, int b )
{
if(a>b) return a;
else return b;
}
int dp[m][m],v[m],w[m];//v表示体积,w表示价值;
int main()
{
int T;
int N,V,i,j;
scanf("%d",&T);// T=1;
memset(dp,0,sizeof(dp));
while(T--)
{
scanf("%d %d",&N,&V);// N=5 V=10
for( i=1; i<=N; i++ )
scanf("%d",&w[i]);// 1 2 3 4 5
for( i=1; i<=N; i++ )
scanf("%d",&v[i]);// 5 4 3 2 1
for( i=1; i<=N; i++ )
for( j=0; j<=V; j++ )
{
if( j-v[i]>=0 )
dp[i][j]=max( dp[i-1][j], dp[i-1][j-v[i]]+w[i] );
}
printf("%d\n",dp[N][V]);
}
return 0;
}
二、完全背包(每件物品都可以放任意次)
样例:有N种物品和一个容量为V的背包,每种物品都有无限件可用。第i种物品的费用是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
需要一个可能已选入第i种物品的子结果f[j-w[i]],所以顺推过去

例题:http://acm.hdu.edu.cn/showproblem.php?pid=1114
代码如下:
#include<stdio.h>
#include<string.h>
const int inf=0x3f3f3f3f;
int dp[10001],p[505],w[505];
int min( int a, int b )
{
if(a<=b)
return a;
else
return b;
}
int main()
{
int i,j,E,F;
int T,W,n;
scanf("%d",&T);
while( T-- )
{
scanf("%d %d",&E,&F);
W=F-E;
scanf("%d",&n);
for( i=0; i<n; i++ )
scanf("%d %d",&p[i],&w[i]);
for( i=1; i<=W; i++ )
dp[i]=inf;
dp[0]=0;
for( i=0; i<n; i++ )
for( j=w[i]; j<=W; j++ )
{
dp[j]=min( dp[j], dp[j-w[i]]+p[i] );
}
if( dp[W] < inf )
printf("The minimum amount of money in the piggy-bank is %d.\n",dp[W]);
else
printf("This is impossible.\n");
}
return 0;
}
本文探讨了背包问题的两种类型——01背包和完全背包。01背包中每种物品最多只能放入一次,而完全背包允许每种物品无限次放入。文章通过举例说明了这两种背包问题的解决思路,并提供了相关例题链接和对应的解题代码,旨在帮助读者理解如何求解背包问题以获得最大价值或费用总和不超过背包容量的情况。
664

被折叠的 条评论
为什么被折叠?



