当前位置:   article > 正文

javascript——m个月饼分给n个人_有一个0.5倍数的数字m,按照最小0.5分配给n个人,分不够的话给0分,用js如何实现

有一个0.5倍数的数字m,按照最小0.5分配给n个人,分不够的话给0分,用js如何实现

题目描述

        中秋节,公司分月饼,m个员工,买了n个月饼,m<=n,每个员工至少分1个月饼,但可以分多个,单人份到最多月饼的个数为Max1,单人分到第二多月饼的个数是Max2,Max1-Max2<=3,。同理,单人分到第n-1多月饼的个数是Max(n-1),单人分到第n多月饼的个数是Max(n),Max(n-1)-Max(n)<=3。请问有多少种分月饼的方法?

输入描述:

第一行输入m n,表示m个员工,n个月饼,m <= n

输出描述:

输出有多少种月饼分法

例:

输入

3 12

输出

6

解法1:动态规划 筛选出差值小于3的分配方法

  1. /**
  2. * @param n 人数
  3. * @param m 月饼数
  4. * @param diff Max(n)-Max(n-1)
  5. */
  6. function main1(n, m, diff) {
  7. if(m < n) {
  8. throw new Error("月饼数小于人数");
  9. }
  10. let result = [];
  11. // 月饼数与人数相等时
  12. if (n === m){
  13. result.push(new Array(n).fill(1));
  14. return result;
  15. }
  16. // 递归
  17. let ways = main1(n, m-1);
  18. ways.forEach(way => {
  19. way.forEach((item, i) => {
  20. let newway = [...way];
  21. newway[i] = item + 1;
  22. newway.sort(); // 将新分配方法排序
  23. if (!isExist(newway,result)){ //排除相同分法
  24. checkDiff(newway, diff) && result.push(newway);
  25. // result.push(newway);
  26. }
  27. });
  28. })
  29. return result;
  30. }
  31. /**
  32. * 比较value数组是否存在总数组中
  33. * @params value 被比较的数组
  34. * @params list 总数组
  35. */
  36. function isExist(value, list){
  37. return list.some(listItem => {
  38. if (value.length !== listItem.length){
  39. return false;
  40. }
  41. return listItem.every((childItem, index) => {
  42. if(value[index] !== childItem){
  43. return false;
  44. }
  45. return true;
  46. })
  47. })
  48. }
  49. function checkDiff(value, diff){
  50. if(typeof diff !== 'number' || diff < 0) {
  51. return true;
  52. }
  53. return value.every((item, index) => {
  54. if(index === 0) return true;
  55. if(item - value[index - 1] > diff){
  56. return false;
  57. }
  58. return true;
  59. })
  60. }

解法2 

  1. /**
  2. * @param n 人数
  3. * @param m 月饼数
  4. * @param diff Max(n)-Max(n-1)
  5. */
  6. function main2(n, m, diff) {
  7. // 如果diff格式错误,则将其置为最大值 得到所有分配方法
  8. if(typeof diff !== 'number' || diff < 0) {
  9. diff = m;
  10. }
  11. // 人数大于月饼数 无法分配
  12. if (n > m) {
  13. return 0;
  14. }
  15. // 每人分一个后 剩余月饼数
  16. const p = m - n;
  17. let count = 0;
  18. for(let k = 0; k < p; k++){
  19. count = count + distribute(n-1, p-k, k, diff);
  20. }
  21. return count;
  22. }
  23. /**
  24. * @param n 剩余未分配人数
  25. * @param p 剩余月饼数
  26. * @param k 当前被分配人得到的月饼数
  27. * @param diff Max(n)-Max(n-1)
  28. */
  29. function distribute(n, p, k, diff) {
  30. if (p <= 0) return 0;
  31. if (n <= 0) return 0;
  32. if (n === 1) {
  33. // 如果最后一个人应该获得的月饼数在剩余月饼数的范围之内
  34. // 则存在新的一种分配方式 返回1
  35. if (p >= k && p <= k + diff) {
  36. return 1;
  37. }
  38. return 0;
  39. }
  40. let ncount = 0;
  41. // 迭代 当前被分配人获得 k+(0~diff) 个月饼时
  42. for (let knext = k; knext <= k + diff; knext++) {
  43. ncount = ncount + distribute(n-1, p-knext, knext, diff);
  44. }
  45. return ncount;
  46. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/Guff_9hys/article/detail/798377
推荐阅读
相关标签
  

闽ICP备14008679号