算法设计_动态规划

基本概念

动态规划应用于子问题重叠的情况,即不同的子问题具有公共的子子问题,动态规划算法对于每个子子问题只求解一次,并将其保存,避免了重复的计算。
动态规划算法设计的四个步骤:

 1.刻画一个最优解的结构特征。
 2.递归地定义最优解的值。
 3.计算最优解的值通常采用自底向上的方法。
 4.利用计算出的信息构造一个最优解。

典型问题

1.钢条切割问题

给定一段长度为n英寸的钢条和一个价格表pi(i=1,2,…,n),求切割钢条的最佳方案使得销售收益rn最大。

解:
状态:定义:d(i)为长度为i英寸钢条的最大收益
状态转移方程: d(n)=max{pn,d(1)+d(n-1),d(2)+d(n-2),…d(n-1)+d(1)},这时也就刻画出了最优解的结构特征,同时也可以看出钢条切割问题满足最优子结构性质。

该问题的状态转移方程也可以转化为d(n) = pi+d(n-i) i=0…n

在动态规划算法中需要仔细安排求解顺序,对于每个子问题之求解一次,并将结果保存下来,所以需要使用额外的内存空间将中间结果保存下来,这也是个典型的时空权衡的例子。

int *cut_rod(int n,int *p){
    int *r = new int[n];
    r[0] = 0;
    for(int i = 1 ; j <= n ; j++){
        q = MIN;
        for(int i = 1 ; i <= j ; j++)
            q=max(q,p[i]+r[j-i]);
        r[j]=q;
    }

    return r[n];
}

2.0-1背包问题

共有n个宝石编号: 0,1,2,…,n-1。 某人身上有一个背包,背包的容量为C。第i个宝石对应的体积和价值分别为V[i]和W[i] 。要装下哪些宝石才能获得最大的利益呢?

状态: d(i,j)表示前i个宝石装到剩余体积为j的背包里能达到的最大价值

状态转移方程: d(i) = max{1, d(j)+1},其中j



#include <iostream>
using namespace std;

int lis(int A[], int n){
    int *d = new int[n];
    int len = 1;
    for(int i=0; i<n; ++i){
        d[i] = 1;
        for(int j=0; j<i; ++j)
            if(A[j]<=A[i] && d[j]+1>d[i])
                d[i] = d[j] + 1;
        if(d[i]>len) len = d[i];
    }
    delete[] d;
    return len;
}
int main(){
    int A[] = {
        5, 3, 4, 8, 6, 7
    };
    cout<<lis(A, 6)<<endl;
    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值