[Algorithm] Meeting hour optimization (Kanpsack problem) and Dynamic programming
For example we have array of meeting objects:
const data = [
{ name: "m1", hours: },
{ name: "m2", hours: },
{ name: "m3", hours: },
{ name: "m4", hours: },
{ name: "m5", hours: }
];
For a day, 8 hours, we want to take as any meetings as possible:
const res = optimizeMeetings(data, );
You should write function 'optimizeMeetings', get the results of selected meetings to attend.
This problem is the same as Knapack problem, we can construct a table:
| hours / total | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 2 | 0 | 2 | 2 | 2 | 2 | 2 | 2 | 2 |
| 4 | 0 | 2 | 2 | 4 | 4 | 6 | 6 | 6 |
| 3 | 0 | 2 | 3 | 4 | 5 | 6 | 7 | 7 |
| 3 | 0 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
| 1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
The max hours we can take is the last row & col value, which in the end should be 8.
Then we should trace back the table to find which items should be included.

Final Code:
/**@description
* When we have our result for Knapsack problem, we want to back trace to get the selected items.
*
* What we need to do is trace form last item of the memo, moving up
*/
const backTrace = (hours, totalHours, memo) => {
function helper(memo, row, col) {
let current = memo[row][col];
let selected = [];
while (current >= && row >= && col >= ) {
// If we reach the first row, then check whether we have the remaining?
// If yes then we need to add this row item into final result
if (row === && current !== ) {
selected.push(row);
break;
} let sameRowPrevCol = memo[row][col - ];
let prevRowSameCol = memo[row - ][col]; if (current !== sameRowPrevCol && prevRowSameCol !== current) {
// Item should be selected if the value with sibling values are differnet
selected.push(row);
// calcuate the remaining
col = current - hours[row] - ;
row = row - ;
} else if (prevRowSameCol === current && current !== sameRowPrevCol) {
// current is coming from previous row with the same column, reset row
row = row - ;
} else if (current === sameRowPrevCol && prevRowSameCol !== current) {
// current is coming from previous column with the same row, reset column
col = col - ;
}
// Update current with new row and new column
current = memo[row][col];
}
return selected;
} return helper(memo, hours.length - , totalHours.length - );
}; const getMaxHours = (hours, totalHours) => {
let memo = [...new Array(hours.length)].map(
x => new Array(totalHours.length)
);
function helper(hours, totalHours, memo) {
for (let row in hours) {
const value = hours[row];
for (let col in totalHours) {
// Fill in the first row
if (!memo[row - ]) {
memo[row][col] = value <= totalHours[col] ? value : ;
continue;
} // if the current value is larger than constrain, we use previous value
const prevRowSameCol = memo[row - ][col];
if (value > totalHours[col]) {
memo[row][col] = prevRowSameCol;
continue;
} // if the current value is equal to constrain, then Max{value, prevRowSameCol}
if (value === totalHours[col]) {
memo[row][col] = Math.max(value, prevRowSameCol);
} // if the current value is smaller than constrain
// Math {value + memo[row - 1][diff]: where diff is constrain-value, prevRowSameCol}
if (value < totalHours[col]) {
const diff = totalHours[col] - value - ;
memo[row][col] = Math.max(
prevRowSameCol,
value + memo[row - ][diff]
);
}
}
}
return memo;
}
memo = helper(hours, totalHours, memo);
const selectedIndex = backTrace(hours, totalHours, memo); return {
memo,
selectedIndex
};
}; function* genearteNumberAry(start, num) {
let i = start;
while (i <= num) {
yield i;
i++;
}
} /**
* Main
*/
/**
* @param meetings: [{name: string, hours: number}]
* @param haveHours: number
*
* @returns [meetings]
*/
function optimizeMeetings(meetings, haveHours) {
const hours = meetings.map(m => m.hours);
const haveHoursAry = Array.from(genearteNumberAry(, haveHours));
const { selectedIndex } = getMaxHours(hours, haveHoursAry);
return selectedIndex.map(i => meetings[i]);
} const data = [
{ name: "m1", hours: },
{ name: "m2", hours: },
{ name: "m3", hours: },
{ name: "m4", hours: },
{ name: "m5", hours: }
]; const res = optimizeMeetings(data, );
console.log(JSON.stringify(res)); // [{"name":"m4","hours":3},{"name":"m3","hours":3},{"name":"m1","hours":2}]
[Algorithm] Meeting hour optimization (Kanpsack problem) and Dynamic programming的更多相关文章
- Codeforces 1503C Travelling Salesman Problem(Dynamic Programming)
题意 大家都是优秀生,这点英文还是看得懂的:点此看题 题解 由于旅行路线成一个环,所以从哪里出发不重要,我们把景点按照 a i a_i ai 排序,不妨就从左边最小的出发.基础的旅行费用 c i c ...
- hdu 4223 Dynamic Programming?
Dynamic Programming? Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Oth ...
- hdu 4972 A simple dynamic programming problem(高效)
pid=4972" target="_blank" style="">题目链接:hdu 4972 A simple dynamic progra ...
- [Optimization] Dynamic programming
“就是迭代,被众人说得这么玄乎" “之所以归为优化,是因为动态规划本质是一个systemetic bruce force" “因为systemetic,所以比穷举好了许多,就认为是 ...
- [Optimization] Advanced Dynamic programming
这里主要是较为详细地理解动态规划的思想,思考一些高质量的案例,同时也响应如下这么一句口号: “迭代(regression)是人,递归(recursion)是神!” Video series for D ...
- HDU-4972 A simple dynamic programming problem
http://acm.hdu.edu.cn/showproblem.php?pid=4972 ++和+1还是有区别的,不可大意. A simple dynamic programming proble ...
- 以计算斐波那契数列为例说说动态规划算法(Dynamic Programming Algorithm Overlapping subproblems Optimal substructure Memoization Tabulation)
动态规划(Dynamic Programming)是求解决策过程(decision process)最优化的数学方法.它的名字和动态没有关系,是Richard Bellman为了唬人而取的. 动态规划 ...
- 最优化问题 Optimization Problems & 动态规划 Dynamic Programming
2018-01-12 22:50:06 一.优化问题 优化问题用数学的角度来分析就是去求一个函数或者说方程的极大值或者极小值,通常这种优化问题是有约束条件的,所以也被称为约束优化问题. 约束优化问题( ...
- [Algorithms] Using Dynamic Programming to Solve longest common subsequence problem
Let's say we have two strings: str1 = 'ACDEB' str2 = 'AEBC' We need to find the longest common subse ...
随机推荐
- luoguP4336 [SHOI2016]黑暗前的幻想乡 容斥原理 + 矩阵树定理
自然地想到容斥原理 然后套个矩阵树就行了 求行列式的时候只有换行要改变符号啊QAQ 复杂度为\(O(2^n * n^3)\) #include <cstdio> #include < ...
- bzoj4399 魔法少女LJJ 线段树合并
只看题面绝对做不出系列.... 注意到\(c \leqslant 7\),因此不会有删边操作(那样例删边干嘛) 注意到\(2, 5\)操作十分的有趣,启示我们拿线段树合并来做 操作\(7\)很好处理 ...
- Python168的学习笔记4
关于普通文本文件的读写 python2.7中,未注明的字符都是以acsii来编码的,而要让字符能够通用,必须声明为unicode. s=u'你好',s.encode('utf8')就是指用utf8来进 ...
- python开发_tkinter_菜单的不同选项
python的tkinter模块中,菜单也可以由你自定义你的风格 下面是我做的demo 运行效果: ====================================== 代码部分: ===== ...
- codevs 1063 合并果子 STL 优先队列
1063 合并果子 Time Limit: 1 Sec Memory Limit: 256 MB 题目连接 http://codevs.cn/problem/1063/ Description 在一 ...
- MySQL在控制台上以竖行显示表格数据
直接在SQL语句后面加\G即可,如: select * from user limit 10\G; 如果想要知道这些参数可以直接在命令行后面加入\?
- jquery获取单选button选中的值
在页面上单选button的代码: <s:iterator value="@com.hljw.cmeav.util.CmeavGlobal@isComMap"> < ...
- web语义化,从松散到实战
GitHub:http://liu12fei08fei.github.io/html/4semantic.html web语义化,从松散到实战 在这篇文章之前,我放弃了很多次,写关于语义化方面的文章: ...
- 使用Enum.TryParse()实现枚举的安全转换
在项目中,有时候会用到领域枚举和DTO枚举的映射和转换.有一个现实的问题是:如果领域枚举项发生变化,而DTO枚举项没有及时更新,这样会造成映射不上的问题.那么,如何避免此类问题呢? 先看领域枚举和DT ...
- MVC中使用CKEditor01-基础
本篇体验在MVC中使用CKEditor,仅仅算思路.基础,暂没有把验证等与CKEditor结合在一起考虑. □ 1 使用NUGET引入CKEditorPM> Install-Package CK ...