动态规划

来源:互联网 发布:太阳黑子与气候数据 编辑:程序博客网 时间:2024/06/05 18:12

使用动态规划解决问题时,需要遵循三个重要步骤:

1.定义子问题;

2.实现反复执行而解决子问题的部分;

3.识别并求解出边界条件;

能够用动态规划解决的著名问题有:

*背包问题:有N件物品和一个容量为V的背包。第i件物品的重量是w[i],价值是v[i]。求解将哪些物品装入背包可使这些物品重量总和不超过背包容量,且价值总和最大。

function knapsack(w,v,c){//w为重量向量,v为价值向量,c为背包总容量    var length = w.length;    var m = [],        x = []; //记录每件物品是否放入背包,0——未放入,1——放入    for(var i=0; i<c; i++){        m[0][i] = 0; //初始化    }    for(var i=1; i<length; i++){        for(var j=1; j<=c; j++){            if(j<w[i]){                 m[i][j] = m[i-1][j];            }else{                m[i][j] = Math.max(m[i-1][j],m[i-1][j-w[i]]+v[i]);                            }        }    }    console.log("背包的最大价值为:" + m[length,c]);    // 各物品装入背包情况    for(var i=c; i>=1; i--){        if(m[i][c]>m[i-1][c]){ //第i件装入背包时            x[i] = 1;            c -= w[i];        }else{  //第i件未装入背包时            x[i] = 0;        }    }}  
*最长公共子序列

第一步:先计算最长公共子序列的长度。
第二步:根据长度,然后通过回溯求出最长公共子序列。

function findLCS(str1,str2){    var length = str1.length,        C = [];    //初始化    for(var i=0; i<=length; i++){        C[i] = [];        for(var j=0; j<=length; j++){            C[i][j] = 0;        }    }    //C[i][j]表示str1的前i个字符及str2的前j个字符的公共子序列长度    for(var i=1; i<=length; i++){        for(var j=1; j<=length; j++){            if(str1[i-1] == str2[j-1]){                C[i][j] = C[i-1][j-1] + 1;                            }else{                C[i][j] = Math.max(C[i-1][j],C[i][j-1]);            }        }    }    console.log("长度:" + C[length][length]);    //回溯求最长公共子序列    var index1 = length,        index2 = length,        result = [];        console.log("length:" + length);    while(index1>0 && index2>0){        if(C[index1][index2] == (C[index1-1][index2-1]+1)){            result.unshift(str1[index1-1]);            index1--;            index2--;        }else if(C[index1][index2] == C[index1-1][index2]){            index1--;        }else{            index2--;        }    }    console.log(result);}var str1 = "abcdefg";var str2 = "avcdery";findLCS(str1,str2);