小于v[i]的都会被跳过。在视频21:00
看了Y老师的DP分析法后,我好像知道了DP为什么广为受人推崇,因为动态规划通过额外的空间将已经搜索过的相似结果(指某些具有相同性质的解的集合)用一个数组空间保存起来了,所以DP中的状态转移方程看上去是某两三个值之间的推导,其实是某两三个集合之间的状态转移。 以上是学渣的一点点小小的总结,不知道正确与否。非常有幸看到如此优秀的讲解视频!
你好,我想问下,下面这个优化过程为什么用f[i,j-v]这个状态来和f[i,j]来进行比较得出规律?
f[i , j ] = max( f[i-1,j] , f[i-1,j-v]+w , f[i-1,j-2v]+2w , f[i-1,j-3v]+3w, .....)
f[i , j-v]= max( f[i-1,j-v] , f[i-1,j-2v] + w, f[i-1,j-2v]+2w , .....)
f[ i ][ j - v ]按照状态集合表示的意思是:前i件物品中,体积不超过j - v[ i ]的最大价值。
是怎么想到要用这个方程f[i,j-v]来和f[i,j]来进行比较得出规律的?
重复看了y总好几次视频,也想不到为什么要用这个方程。
选取相邻两个状态方程来比较的意思吗?这句话对也不对。首先,根据我的理解,DP的状态转移方程肯定是要根据相邻的状态方程来进行递推的,一般都是用f(i-1,j) / f(i,j-1) / f(i-1,j-1)来递推。 但是在这一题而言,使用f[i,j-v] 是观察到了在这个状态转移方程中: f[i , j ] = max( f[i-1,j] , f[i-1,j-v]+w , f[i-1,j-2v]+2w , f[i-1,j-3v]+3w, .....) ,如果我们将j替换成j-v 的话,就可以表达max函数中除了第一项之外的其他所有项。
为什么这里的二维dp里这样写是对的
for (int i = 1; i <= n; i ++ )
for (int j = 0; j <= m; j ++ )
{
f[i][j] = f[i - 1][j];
if (j - v[i] >= 0) 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];
if (j - v[i] >= 0) f[i][j] = max(f[i - 1][j], f[i - 1][j -v[i]] + w[i]);
}
这里的f[i][j] = f[i - 1][j]有什么含义啊。
还有就是这样写也是错误的
for (int i = 1; i <= n; i ++ )
for (int j = v[i]; j <= m; j ++ )
{
f[i][j] = f[i - 1][j];
f[i][j] = max(f[i][j], f[i][j - v[i]] + w[i]);
}
因为第二种如果注释掉的话,那么 j < v[i] 的时候,f [i][j] 就没有被计算
f[i][j] = f[i - 1][j] 那行的意思是 在 j < v[i] 的时候,因为 f[i - 1][j -v[i]] + w[i] 这项不成立,所以 f[i][j] 直接等于 f[i - 1][j]
对滴。
确实,二维的还是得多写一行,一维的更省事
dp[i][j] = Math.max(dp[i-1][j],Math.max(dp[i-1][j-v]+w,dp[i-1][j-2v]+2w),…,dp[i-1][j-kv]+kw);
dp[i][j-v] = Math.max(dp[i-1][j-v],Math.max(dp[i-1][j-2v]+w,dp[i-1][j-3v]+2w),…,dp[i-1][j-(k+1)v]+kw);
为什么我推出来的式子dp[i][j-v]比dp[i][j]多了一个dp[i-1][j-(k+1)v]+kw),因为第一个式子的dp[i-1][j]第二个式子没有,两个式子的项数应该时一样的,那么第二个应该比第一个多了一个j-(k+1)*v吧?