HLOJ 1006 0-1背包问题
HDU 2602 Bone Collector类似,但要注意输入顺序,问题规模,最重要的是重量为0的骨头居然也有价值的!
#include<iostream>
using namespace std;
#define N 401
#define M 1501
int f[N][M]; //下标从1开始用
//n种物品,各种物品的容量、价值分别在w、v数组中;c为背包容量
//状态:f[i][j],使用前i种物品构成背包容量为j时能获得的最大价值
//转移方程:f[i][j]=max(f[i-1][j], f[i-1][j-w[i]]+v[i]),
//转移方程中,前者表示不用第i种物品,后者表示用第i种物品
//初值:0种物品时任何容量下能获得的最大价值都为0
//结果:f[n][c]
int max(int a, int b)
{
if(a>b)
return a;
else
return b;
}
int dpKnapSack(int n, int w[], int v[], int c)
{
int i,j;
for (j=0; j<=c; j++) f[0][j]=0;
for (i=1; i<=n; i++)
{
//若有0容量但有价值的物品,则j从0开始,如 HDU 2602 Bone Collector
for (j=1; j<=c; j++)
{
if (j<w[i])//当前容量为j时,第i种物品放不下,肯定不用该物品
f[i][j]=f[i-1][j];
else //在用与不用第i种物品中取大者
f[i][j]=max(f[i-1][j], f[i-1][j-w[i]] + v[i]);
}
}
return f[n][c];
}
int main()
{
#ifndef ONLINE_JUDGE
freopen("e:\\input.txt","r",stdin);
#endif
int w[N], v[N];
int n, c, i;
while(scanf("%d%d",&n, &c)!=EOF)
{
for(i=1;i<=n;i++) scanf("%d", &w[i]);
for(i=1;i<=n;i++) scanf("%d", &v[i]);
printf("%d\n", dpKnapSack(n, w, v, c));
}
return 0;
}
本文探讨了背包问题及其变体——骨头收集问题的解决策略,重点关注输入顺序、问题规模及特殊情况下(如重量为0的骨头)的价值处理。通过详细解释状态转移方程,提供了一个通用的动态规划求解方法,并通过实例代码展示了解决过程。
3516

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



