动态规划01背包学习日记

10月15日

#include<iostream>
using namespace std;
const int N=1010;

int f[N][N];
int v[N],w[N];
int n,m;

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>=v[i])
		f[i][j]=max(f[i-1][j],f[i-1][j-v[i]]+w[i]);
	}
	cout<<f[n][m]<<endl;
	return 0;
}

状态属性:f[i][j]表示在在前i个物品中j的体积下最大的重量是多少

状态方程的解释:01背包有两种状态。第一种为前i种第i个物品的不取状态,所以则f[i][j]=f[i-1][j],显然不取则两者状态相同,第i个物品不取是因为此时不能取(v[i]>j)无法取。第二种为前i种物品中第i个品物取的状态(v[i]<=j),所以取f[i-1][j-v[i]]+w[i]和f[i-1][j]的最大值

//01背包一维的优化
#include<iostream>
using namespace std;
const int N=1010;

int f[N];
int v[N],w[N];
int n,m;

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=m;j>=v[i];j--)
	{
		f[j]=max(f[j],f[j-v[i]]+w[i]);
	}
	cout<<f[m]<<endl;
	return 0;
}

优化过程即为为状态转移方程的等价

一维优化顾名思义,去掉一个维度,那么我们删掉f[i][j]中[i]的维度 。为什么j的枚举从m开始向后枚举而不是从v[i]开始向前枚举呢?如果此时我们从v[i]枚举,我们可能会使用到本应该在i-1中的状态而却用在了i状态下,简而言之因为我们去掉一个维度我们并不知道此时v[i]时f[i-1][j]还是f[i][j]下的体积。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值