DP(01背包问题)

这篇博客介绍了如何使用动态规划解决经典的01背包问题。通过二维数组f[i][j]表示前i个物品中挑出的最大价值且不超过j空间的情况。博主详细解析了两种状态转移情况,并给出了两种实现方式,包括标准二维数组和一维优化后的代码实现。文章重点在于理解和应用动态规划的思路。
摘要由CSDN通过智能技术生成

01背包问题

DP

题意:在给定的空间下,从面前的每个仅一个的物品中选出最大的价值。

因为公式短,思维量大,所以考察频率高。

对每个东西,有两种状态

其一:不拿(f[i][j]=f[i-1][j])

其二:拿(f[i][j]=f[i-1][j-v[i]+w[i])

#include <iostream>

using namespace std;

const int N = 1e6+10;
int n,m;
int v[N],w[N];
//f[i][j]表示前i个物品中挑出的最大值,所占空间不超过j
int f[N][N];
int main() 
{
	cin>>n>>m;
	for(int i=1;i<=n;i++) cin>>v[i]>>w[i];
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++){
			f[i][j]=f[i-1][j];
			if(j>=w[i]) f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i]);
		}
	cout<<f[n][m]<<endl;
}

一维简化:

一维简化,可以发现,签名的i-1基本上没有使用,所以我们可以进行操作,但是需要注意顺序。

for(int i=1;i<=n;i++)

        for(int j=m;j>=1;j++){

                f[j]=max(f[j],f[j-v[i]]+w[i]);

        }

cout<<f[m]<<endl;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值