JavaScript 动态规划 & 贪心算法

·  阅读 7595

动态规划

斐波拉契数列

``````0，1，1，2，3，5，8，13，21，34，55，......

``````function fibo (n) {
if (n <= 0)  return 0;
if (n === 1) return 1;
return fibo(n - 1) + fibo(n - 2);
}

``````function fibo (n) {
if (n <= 0) return 0;
if (n <= 1) return 1;
var arr = [0, 1];
for (var i = 2; i <= n; i++) {
arr[i] = arr[i - 1] + arr[i - 2];
}
return arr[n];
}

``````function fibo (n) {
if (n <= 0) return 0;
if (n <= 1) return 1;
var res, a = 0, b = 1;
for (var i = 2; i <= n; i++) {
res = a + b;
a = b;
b = res;
}
return res;
}

``````function fibo (n) {
if (n <= 0) return 0;
if (n <= 1) return 1;
var a = 0, b = 1;
for (var i = 2; i <= n; i++) {
b = a + b;
a = b - a;
}
return b;
}

寻找最长公共子串

``````function maxSubString (str1, str2) {
if (!str1 || !str2) return '';
var len1 = str1.length,
len2 = str2.length;
var maxSubStr = '';
for (var i = 0; i < len1; i++) {
for (var j = 0; j < len2; j++) {
var tempStr = '',
k = 0;
while ((i + k < len1) && (j + k < len2) && (str1[i + k] === str2[j + k])) {
tempStr += str1[i + k];
k++;
}
if (tempStr.length >  maxSubStr.length) {
maxSubStr = tempStr;
}
}
}
return maxSubStr;
}

背包问题

``````function knapsack (capacity, objectArr, order) {
if (order < 0 || capacity <= 0) {
return 0;
}
if (arr[order].size > capacity) {
return knapsack(capacity, objectArr, order - 1);
}
return Math.max(arr[order].value + knapsack(capacity - arr[order].size, objectArr, order - 1),
knapsack(capacity, objectArr, order - 1));
}

console.log(knapsack(16, [
{value: 4, size: 3},
{value: 5, size: 4},
{value: 10, size: 7},
{value: 11, size: 8},
{value: 13, size: 9}
], 4)); // 23

0-1背包问题子结构：选择一个给定第 i 件物品，则需要比较选择第 i 件物品的形成的子问题的最优解与不选择第 i 件物品的子问题的最优解。分成两个子问题，进行选择比较，选择最优的。

``````f[i][w] = max{ f[i-1][w], f[i-1][w-w[i]]+v[i] }

``````function knapsack (capacity, objectArr) {
var n = objectArr.length;
var f = [];
for (var i = 0; i <= n; i++) {
f[i] = [];
for (var w = 0; w <= capacity; w++) {
if (i === 0 || w === 0) {
f[i][w] = 0;
} else if (objectArr[i - 1].size <= w) {
var size = objectArr[i - 1].size,
value = objectArr[i - 1].value
f[i][w] = Math.max(f[i - 1][w - size] + value, f[i - 1][w]);
} else {
f[i][w] = f[i - 1][w];
}
}
}
return f[n][capacity];
}

``````f[w] = max{ f[w], f[w-w[i]]+v[i] }

``````function knapsack (capacity, objectArr) {
var n = objectArr.length;
var f = [];
for (var w = 0; w <= capacity; w++) {
for (var i = 0; i < n; i++) {
if (w === 0) {
f[w] = 0;
} else if (objectArr[i].size <= w) {
var size = objectArr[i].size,
value = objectArr[i].value
f[w] = Math.max(f[w - size] + value, f[w] || 0);
} else {
f[w] = Math.max(f[w] || 0, f[w - 1]);
}
}
}
return f[capacity];
}

贪心算法

背包问题

``````function knapsack (capacity, objectArr) {
// 首先按性价比排序, 高 -> 低
objectArr.sort(function (a, b) {
return parseFloat(b.value / b.size) - parseFloat(a.value / a.size);
});
// 记录物品个数
var n = objectArr.length;
// 记录已经选中尺寸，已选最大的最大价值
var selected = 0,
maxValue = 0;
for (var i = 0; i < n && selected < capacity; i++) {
var size = objectArr[i].size,
value = objectArr[i].value;
if (size <= capacity - selected) {
maxValue += value;
selected += size;
} else {
// 计算比例
maxValue += value * ((capacity - selected) / size);
selected  = capacity;
}
}
return maxValue;
}