数据结构与算法的JavaScript描述——动态规划
说明:以下部分均为《数据结构与算法的JavaScript描述》学习内容及笔记。
动态规划是什么?
- 动态规划有时被认为是一种与递归相反的技术。递归是从
顶部开始
将问题分解,通过解决掉所有分解出小问题的方式来解决整个问题。动态规划解决方案从底部开始
解决问题,将所有小问题解决掉,然后合并成一个整体解决方案,从而解决整个大问题。
动态规划实例:计算菲波那切数列
//递归实现:效率低,有太对值在递归调用中重新计算。
function recurFib(n){
if(n<2){
return n;
}else{
return recurFib(n-1) + recurFib(n-2);
}
}
//动态规划实现
function dynFib(n){
var val=[];
for(var i=0;i<=n;i++){
val[i]=0;
}
if(n==1||n==2){
return 1;
}else{
val[1]=1;
val[2]=2;
for(var i=3;i<=n;i++){
val[i]=val[i-1]+val[i-2];
}
return val[n-1];
}
}
//迭代实现
function iterFib(n){
var last=1;
var nextLast=1;
var result=1;
for(var i=2;i<n;i++){
result=last+nextLast;
nextLast=last;
last=result;
}
return result;
}
动态规划实例:寻找最长公共子串
function lcs(word1,word2){
var max=0;
var inedx=0;
//第一步:初始化数组
var lcsarr=new Array(word1.length+1);
for(var i=0;i<=word1.length+1;i++){
lcsarr[i]=new Array(word2.length+1)
for(var j=0;j<word2.length+1;j++){
lcsarr[i][j]=0;
}
}
//第二步:构建匹配记录表
for(var i=1;i<=word1.length;i++){
for(var j=1;j<=word2.length;j++){
if(word1[i-1]==word2[j-1]){
lcsarr[i][j]=lcsarr[i-1][j-1]+1;
}else{
lcsarr[i][j]=0;
}
if(max<lcsarr[i][j]){
//匹配字符串的长度
max=lcsarr[i][j];
//当前的i值
index=i;
}
}
}
//第三步:确认从哪里构建最长公共子串
var str="";
if(max==0){
return "";
}else{
for(var i=index-max;i<=max;i++){
str+=word2[i];
}
return str;
}
}
动态规划实例:背包问题
function max(a, b){
return (a>b)?a:b;
}
//capcity:容积、size:物品尺寸、value:物品价值、n:物品数
function dKnapsack(capacity,size,value,n){
var k=[];
for(var i=0;i<=capacity+1;i++){
k[i]=[];
}
for(var i=0;i<=n;i++){
for(var w=0;w<=capacity;w++){
if(i==0||w==0){
k[i][w]=0;
}else if(size[i-1]<=w){
k[i][w]=max(value[i-1]+k[i-1][w-size[i-1]],k[i-1][w]);
}else{
k[i][w]=k[i-1][w];
}
}
}
return k[n][capacity];
}