POJ - 3624 (01背包问题)(动态规划-滚动数组)

题意:

        往手镯上镶嵌宝石,手镯总重量有上限,要求手镯的总价值最大。

        本质就是一个01背包问题。


解题思路:

        下面开始分析01背包问题。

        动态规划问题主要是找到子问题,即一旦确定了第i个状态,就可以直接推出第i+1个状态。(有后效性)


以题目给出的数据举例:

  4 6     n     m
① 1 4    w[i]  v[i]
② 2 6
③ 3 12
④ 2 7

设F[j]为背包剩余容积为j时背包所能达到的最大价值。(j <= m)

取①号物体时,如果j < 1,则F[0] = 0,如果j >= 1时,F[1]=F[2]=...=F[6]=4;

取②号物体时,如果j < 2,则F[1]保持不变,仍为4;

                       如果j >= 2,则可以选择取或者不取②号物体,因此F[j] = max(F[j],F[ j-w[i] ]+v[i]);(如下所示)

取:F[2] = F[ j-w[i] ]+v[i] = F[0]+v[2]=0+6=6;

       F[3] = F[ j-w[i] ]+v[i] = F[1]+v[2]=4+6=10;

       F[4] = F[ j-w[i] ]+v[i] = F[2]+v[2]=4+6=10;...F[5]=F[6]=10;

不取:F[1]=F[2]=...=F[6]=4;

因此F[j]=max(取,不取)=max(F[j],F[ j-w[i] ]+v[i]);


取③号物体...取④号物体,依次类推

下面是代码实现:

#include <cstdio>
#include <algorithm>

using namespace std;

int w[3410],v[3410]; //记录各个物体的重量和价值
int f[12900];        //记录当背包剩余重量为j时的背包最大价值

int main()
{
	int n,m;//n是个数,m是最大重量
	
	scanf("%d%d",&n,&m);
	for(int i = 0;i < n;i++)
	{
		scanf("%d%d",&w[i],&v[i]);	
	} 
	for(int i = 0;i < n;i++)
	{
		for(int j = m;j >= 1;j--)
		{
			if(j >= w[i])
			{
				f[j] = max(f[j],f[j-w[i]]+v[i]);//取还是不取 
			} 
		}
	}
	sort(f,f+m+1);
	printf("%d\n",f[m]);
	return 0;	
} 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Gene_INNOCENT

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值