dpdpdpdpdpdp

来一场说走就走的旅程,来一个说学就学的dp。

时间匆匆,走的匆匆,转眼离来学校听老师讲dp已经过去好久好久了,可是,菜鸡的我却还是什么都不会,说实话就要退役了,所以,一切的一切,只是为了避免“轻轻的离去不带走一片云彩”的悲哀。

现在学,只是为了学会,并不再是考试是拿到多少分数。吼吼吼吼吼吼吼。

01背包

有N件物品,第i件物品体积为Vi,价值为Wi,容积为M的背包,要求选择几件物品使得总体积不超过M的情况下,总价值最大。

上代码:

for(int i=1;i<=n;i++)
{
   
	for(int j=0;j<=m;j++)
		a[i][j]=a[i-1][j];
	for(int j=v[i];j<=m;j++)
		a[i][j]=max(a[i-1][j],a[i-1][j-v[i]]+w[i]);	
}
for(int i=0;i<=m;i++)
		ans=max(ans,a[n][j]);

一定是在想为什么是选择用(1~n),( 0~m)两个来做循环, 实 际上i是选择第i个物品,在i的循环下面还有一个j,这个j,就是用来在不同的状态下,选择i件物品时在之前选择不同体积情况下的最佳,在最后把所有不同的状态缩减成m中,用他们来比较就行。所以在最后必然是挨着从(1~n)选择物品选还是不选,到最后的状态一定都是到n的,所以a[i][j]中的i,是可以省掉的,是可以用一维数组来降低空间上的消耗。

至少我是懂了。(dp不就是用数组写的dfs,记录的也是每一种状态,但是是更有逻辑,记录的是美中状态的最佳,相当于dp在写的过程中不断的去淘汰一些结果)。

完全背包

有n个有自己体积价值的物品,每种可以选择不限次数,来装一个体积为m背包,使总价值最大。

对于完全背包,先靠着从01背包学来的思路,你是完全可以想出的,你或许是可以直接跳过三重循环,不选第i件物品和选择非0次 i 物品,f[i][j]=f[i-1][j],f[i][j]=max(f[i][j],f[i][j-v[i]]+w[i])
所以可以直接代码:

for(int i=1;i<=n;i++)
	{
   
		for(int j=0;j<=m;j++)
			f[i][j]=f[i-1][j];
		for(int j=v[i];j<=m;j++) 
			f[i][j]=max(f
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值