回朔法与动态规划的思考

来源:互联网 发布:一个域名成就一个梦想 编辑:程序博客网 时间:2024/05/29 18:14

以下是本人对回朔法与动态规划的思考,不当之处还请轻喷指正,谢谢!微笑

回朔法与动态规划可以说是在某种程度上两种截然不同对立的方法:回朔法从头考虑结果,而动态规划从结果着手考虑;回朔法一般用递归实现,而动态规划一般是循环实现;回朔法耗时、效率低,而动态规划运行速度快、效率高;回溯法很容易保存路径,而动态规划却不易保存路径。

举个例子:求一组正整数中能否由一个或几个元素相加,结果和等于给定值(简单考虑,假设元素这些正整数的值都是小于等于给定值的)

回朔法代码如下示:

void addToTarget(vector<int >&v,int n,int target,int sum,int index,bool &result)//调用时addToTarget(v,n,target,0,0,result);
{
if(result)
return;
if(sum==target)
{
result=true;
return;
}
if(index<n)
{
addToTarget(v,n,target,sum+v[index],index+1,result);//当前index下标元素加到sum里的情况
addToTarget(v,n,target,sum,index+1,result);//当前index下标元素不加到sum里的情况

}

可以看出,这是01背包问题,条件就是恰好等于给定值,动态规划的代码如下示:

void addToTarget(vector<int >&v,int n,int target,bool &result)//调用时addToTarget(v,n,target,result);
{
int i,j,sum=0;
int dp[target];
memset(dp,0,sizeof(dp));
dp[0]=1;
for(i=0;i<n;++i)
{
for(j=target;j>=v[i];--j)
{
if(dp[j-v[i]])
dp[j]=1;
if(dp[target])
{
result=true;
return;
}
}
}
}

所以,当用回溯法不能很好滴解决问题(比如运行超时)时,可以逆向考虑一下动态规划;当用动态规划可以很快滴判定是否有解,但如果需要保存路径时,这是就可以考虑用回朔法来代替动态规划了。

比如下面这个例子用回朔法是超时的,但是用动态规划就Ok了---------------------leetcode上的https://leetcode.com/problems/house-robber/

回溯法代码:

class Solution {
public:
    void robmoney(vector<int>&v,int n,int index,int sum,int &max)
    {
        if(index>=n)
        {
            if(sum>max)
                max=sum;
            return;
        }
        robmoney(v,n,index+2,sum+v[index],max);
        robmoney(v,n,index+1,sum,max);
    }
    int rob(vector<int> &num) {
       if(num.size()<1)
        return 0;
        if(num.size()==1)
            return num[0];
        int max=INT_MIN;
        robmoney(num,num.size(),0,0,max);
        return max;
    }
};


动态规划代码:

class Solution {
public:
    int rob(vector<int> &num) {
       if(num.size()<1)
        return 0;
        if(num.size()==1)
            return num[0];
        int i,j,n=num.size(),max;
        int dp[n];
dp[0]=0;
dp[1]=num[0];
max=dp[1];
for(i=2;i<=n;++i)
{
if(dp[i-1]>(dp[i-2]+num[i-1]))
dp[i]=dp[i-1];
else
dp[i]=dp[i-2]+num[i-1];
if(dp[i]>max)
max=dp[i];
}
        return max;
    }
};





0 0
原创粉丝点击