算法-动态规划
来源:互联网 发布:全国网络平台监管系统 编辑:程序博客网 时间:2024/06/06 07:45
what 基本思想:
1、分解成若干子问题
2、求解子问题
3、从子问题的解得到原问题的解
从基本思想上看其与分治很像,他们的区别在于子问题是否独立,子问题之间没有关系是分治,子问题不独立则是动态规划。
how 求解步骤:
1、找出最优解的性质,刻画其结构特征
2、递归地定义最优解的值
3、以自底向上的方式计算出最优值
4、根据最优值信息,构造最优解
where 什么时候适用
存在最优子结构
重叠子问题
动态规划最核心的部分就是运用了递归,不断地求子问题的最优解
典例 0-1背包分析
(1) 0-1背包问题的最优解的结构
决定那些物品放入背包,那些不放,如果放入了n,则其子问题是从n-1个物品选择放在容量W-w(n)背包,如果没有放入n,则从n-1个物品中选择放在容量为W背包中,这构成子问题
(2)递归定义最优解的值
c[i,w]=0 i=0,或w=0
c[i,w]=c[i-1,w] w[i]>w
c[i,w]=max{c[i-1,w-wi]+vi,c[i-1,w]} ,i>0且wi<=w
(3)计算背包问题最优解值
代码中体现了上述分段函数的情况
int KnapsackDP(int n,int*Weights,float* Values) { int i,w,W; /*为二维数组申请空间*/ int** c=(int **)malloc(sizeof(int *)*(n+1)); for(i=0;i<=n;i++){ c[i]=(int *)malloc(sizeof(int *)*(W+1)); } /*初始化二维数组*/ for(w=0;w<=W;w++){ c[0][w]=0; } for(i=1;i<=n;n++){ c[i][0]=0; for(w=1;w<=W;w++){ /*如果物品重量小于背包的剩余重量*/ if(Weights[i-1]<=w){ /*第i个物品放进去的价值大于不放的价值*/ if(Values[i-1]<=w){ /* 第i个物品放入背包*/ c[i][w]=Values[i-1]+c[i-1][w-Weights[i-1]]; } else{ /* 第i个物品不放入背包*/ c[i][w]=c[i-1][w]; } } else{ c[i][w]=c[i-1][w]; } } } return c;}
时间复杂度O(nW)
(4)求最优解
void OutputKnapsackDP(int n,int W,int *Weights,float *Values,int **c){int x[n];int i;for(i=n;i>1;i--){if(c[i][W]==c[i-1][W]){ /* 重量为W的最优选择的背包中不包含该物品*/x[i-1]=0;}else{x[i-1]=1;W=W-Weights[i-1]; /* 更新背包目前的最大容量*/}}if(c[1][W]==0){ /*第一个物品不放入背包*/x[0]=0;}else{x[0]=1; /*第一个物品放入背包*/}for(i=0;i<n;i++){if(x[i]==1){printf("Weight:%d,Value:%f\n",Weights[i],Values[i]);}}}
时间复杂度O(n)
总结:
构造算法最优解的思想和步骤理解了,代码就很容易看明白了,然后仔细看里面变量的取值,循环的条件,判断条件,整个算法就没有问题, 如果遇到动态规划的题,就照着整个步骤认真思考,这样会好很多。
0 0
- 算法--动态规划算法
- 动态规划算法剖析
- 动态规划算法
- 初识动态规划算法
- 动态规划算法
- 动态规划算法剖析
- 动态规划算法
- 动态规划算法剖析
- 动态规划算法
- 动态规划算法实现
- 动态规划算法
- 动态规划算法
- 动态规划算法之一
- 动态规划算法备忘
- 动态规划 --压缩算法
- 动态规划算法
- 动态规划算法
- 动态规划算法解析
- 简单的学生信息处理程序实现
- android关闭日志
- C++继承:公有,私有,保护
- hdu 5971 Wrestling Match(队列)
- 将字符存储到带有头结点的单向链表中
- 算法-动态规划
- 动态Fragment 切换
- 1951: [Sdoi2010]古代猪文
- 1106
- Codeforces 710E Generate a String【dp】好题!
- 编译连接的整个过程和详细的每个过程
- 用view画圈带字
- leetCode练习(128)
- Retrofit 原理 运行机制详解