POJ 3624 Charm Bracelet 0-1背包

本文详细解析了一道典型的0-1背包问题,通过构建状态转移方程并使用滚动数组来优化空间复杂度,提供了完整的C++代码实现。

传送门:http://poj.org/problem?id=3624


题目大意:XXX去珠宝店,她需要N件首饰,能带的首饰总重量不超过M,要求不超过M的情况下,使首饰的魔力值(D)最大。


0-1背包入门题。

可构建状态转移方程:

dp [ i ] [ v ]= max ( dp[ i-1 ] [ v ], dp[ i-1 ][ v- W[ i ] ]+d[ i ] ] )

但是这样空间太大,可以用滚动数组解决。

		for(int i=1;i<=N;i++)
		{
			for(int j=M;j>=w[i];j--)
			{
				f[j]=max ( f[j] , f[j-w[i]]+d[i]);
			}
		}


为什么这样做是正确的呢?f数组是从上到下,右到左计算的,计算f ( i, j)之前, f( j )保存的就是 f(i-1 ,j)的值,f ( j-w )就是 f(i-1 ,j-w)的值,所以f[j]=max ( f[j] , f[j-w[i]]+d[i]); 就把

f(i-1 ,j-w[i]) +d[i] 和 f(i-1 ,j)中大的保存起来。

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=12880+10;
int f[MAXN],w[MAXN],d[MAXN];
int main()
{
	int N,M;
	while(~scanf("%d%d",&N,&M))
	{
		for(int i=1;i<=N;i++)
			scanf("%d%d",&w[i],&d[i]);

		memset(f,0,sizeof(f));
		
		for(int i=1;i<=N;i++)
		{
			for(int j=M;j>=w[i];j--)
			{
				f[j]=max ( f[j] , f[j-w[i]]+d[i]);
			}
		}

		printf("%d\n",f[M]);
	}
}



当然也可以边输入边处理:

#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int MAXN=12880+10;
int f[MAXN],w,d;
int main()
{
	int N,M;
	while(~scanf("%d%d",&N,&M))
	{
		memset(f,0,sizeof(f));		
		for(int i=1;i<=N;i++)
		{
			scanf("%d%d",&w,&d);
			for(int j=M;j>=w;j--)
			{
				f[j]=max ( f[j] , f[j-w]+d );
			}
		}
		printf("%d\n",f[M]);
	}
}


转载于:https://www.cnblogs.com/murmured/p/5004255.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值