首页 > 其他 > 详细

【大家明白才是真的明白】动态规划算法什么时候能用一维数组解问题

时间:2014-04-01 21:13:56      阅读:801      评论:0      收藏:0      [点我收藏+]

先看三则算法的代码:

0-1 背包问题:

int dpf[N+1][W+1]; //数组从0开始
int dp_solve()
{
	for(int i=0; i<N;i++)
		for(int j=0; j<=W;j++)
			if(j<w[i])
				dpf[i+1][j]=dpf[i][j];
			else
			    dpf[i+1][j]=max(dpf[i][j],dpf[i][j-w[i]]+v[i]);
	return dpf[N][W];
}

完全背包问题:

int dp[N+1][W+1]; //数组从0开始
int dpsolve()
{
	for(int i=0; i<N;i++)
		for(int j=0; j<=W;j++)
			if(j<w[i])
			    dp[i+1][j]=dp[i][j];
			else
			    dp[i+1][j]=max(dp[i][j],dp[i+1][j-w[i]]+v[i]);
	return dpf[N][W];
}

LCS最大公共子序列问题:

int dp[m+1][n+1];
int Lcs()
{
	 for(int i=0;i<m;i++)
		 for(int j=0;j<n;j++)
			if(s1[i]==s2[j])
			  dp[i+1][j+1]=  dp[i][j]+1;
			else
			  dp[i+1][j+1]=  max(dp[i+1][j],dp[i][j+1]);
	 return dp[m][n];
}


其中,0-1背包问题 和 完全背包问题可以简化为使用一个 数组来实现,如下:

0-1 背包问题 (一维数组DP):

int dp[W+1]; //数组从0开始
int dp_solve()
{
	for(int i=0; i<N;i++)
		for(int j=W; j>=w[i];j--)
		    dp[j] = max( dp[j], dp[j-w[i]]+v[i]);
	return dp[W];
}


完全背包问题(一维数组DP):

int dp[W+1]; //数组从0开始
int dp_solve()
{
	for(int i=0; i<N;i++)
		for(int j=w[i]; j<=W;j++)
		    dp[j] = max( dp[j], dp[j-w[i]]+v[i]);
	return dp[W];
}


而对于LCS,我们无能为力,分析其原因,可以发现,当 DP算法当前的状态 dp[i+1][j+1]  和 dp[i][j] , dp[i-p][j-q] 等值相关时,如下图所示D 为当前状态,C代表同行前置状态,B代表同列上层状态, A 代表D的上层并且前置状态 。 

bubuko.com,布布扣

设 D =  max {  fun(A), fun(B), fun(C) }

(1) 当 D = max {  fun(A), fun(B) }   即D仅和 A 、B 相关,可以使用一维数组优化,其二级循环 为 从大到小,(因为要使用到 上一层A 状态相关,从小到大 会更新A 的状态),如下代码:

  

for(int i=0; i<N;i++)
     for(int j=M; j>=0;j--)
		// loop codes

(2) 当 D =  max {  fun(B), fun(C) } 即D 仅和 B、C相关,可以使用一维数组优化,其二级循环为从小到大,(因为要使用本层状态C的最新值,所以需要先更新C,再考虑D),如下代码:

for(int i=0; i<N;i++)
	for(int j=M; j>=0;j--)
		// loop codes

(3)  D =  max {  fun(A), fun(C) }  即 D 和 A、C 存在关联时,不可以使用一维数组优化,因为 D 和 A 相关,那么要求 二级循环从大到小,而D和C相关,却要求二级循环从小到大。矛盾,所以不可行。


当我们遇到一维数组无法优化 二级 DP 内存消耗时,我们也可以用一个绝对靠谱的方法,也就是交替法,使用两个一维数组搞定(如 dp[2][M]).


【大家明白才是真的明白】动态规划算法什么时候能用一维数组解问题,布布扣,bubuko.com

【大家明白才是真的明白】动态规划算法什么时候能用一维数组解问题

原文:http://blog.csdn.net/tbwood/article/details/22747215

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!