拆分自然数:纯while实现(Part 2

在拆分自然数:纯while实现 (Part 1 - 思路) 这篇文章里面,我提供了解答Jeff《编程小练习:拆分自然数》问题的一种解答思路,并且使用了两个例子来解释这种思路,不知道你是否已经成功利用这种思路解题了呢?

首先,这道题的搜索域是什么?那就是[min, min, min, ..., min]到[max, max, max, ..., max],或者是它的子集。就算你完全不懂算法,我相信你凭直觉也知道要在[min, min, min, ..., min]到[max, max, max, ..., max]之间搜索。因此,一个算法好不好,就看你能否有效缩小搜索域了。

在不缩小搜索域的情况下,你可以排列组合出搜索域内的所有可能性,逐一验证是否为所求解,这也就是Jeff的DoSimple示例所做的。接着,为了保持解的不重复性,你可能想到了有效解一定是一个不下降序列,因此对所有非不下降序列进行剪枝,这也就是Jeff的DoBetter示例所做的事情。然后,你需要把不下降序列中总和不等于 sum的情况给砍掉,这个剪枝就是最难的一个剪枝了,也就是DoBest所做的事情。

Jeff 在DoBest中的做法是,对于当前操作的第i位,求得itemMinInclusive与itemMaxInclusive,且 minInclusive <= itemMinInclusive <= itemMaxInclusive <= maxInclusive,其中[minInclusive, itemMinInclusive)和(itemMaxInclusive, maxInclusive]这两个区间的取值是无效的,只有[itemMinInclusive, itemMaxInclusive]区间的取值才是有效的。

dragonpig的展开采用了try方式的剪枝,虽然也把无效枝剪掉了,但在循环上还是要遍历到无效枝的首个无效节点,必须在上面try一下看返回false才剪掉,因此性能介于DoBetter与DoBest之间。徐少侠的展开进行了有效的剪枝,在时间复杂度上是与DoBest一致的,不过缓存数据占用空间为实际状态所需空间的3倍,这些空间其实是浪费掉的。我认为比较理想的做法是仅仅缓存sum值,而不缓存下界(即itemMinInclusive)与上界(即itemMaxInclusive),这样是保证性能的前提下最省空间的。至于为什么我说混存下界与上界没用,看一下我的写法就知道了:

function main(m, n, min, max) {
 var array = new Array(n);
 var i = 0;

 var write = function() {
   console.log(m + ' = ' + array.join(' + '));
 };

 var scan = function() {
   if (scan.start) {
    scan.start = false;
    scan.sum = 0;
   }
   scan.sum += array[i];
   return (array[i] > array[n - 1] - 2);
 };

 var step = function() {
  array[i]++;
  fill.sum = scan.sum - array[i];
  i++;
 };

 var fill = function() {
   while (i < n) {
    array[i] = Math.max((fill.sum - (n - i - 1) * max), ((i == 0) ? min : array[i - 1]));
    fill.sum -= array[i];
    i++;
   }
   i--;
 };

 fill.sum = m;
 fill();
 write();
 while (true) {
  scan.start = true;
  while (i >=0 && scan()) {
   i--;
  }
  if (i < 0) {
   break;
  }
  step();
  fill();
  write();
 }
}

时间: 2025-01-21 06:19:40

拆分自然数:纯while实现(Part 2的相关文章

拆分自然数:纯while实现(Part 1

我先问大家一个问题,写一个函数按顺序输出所有的4位二进制数(即:0000, 0001, 0010, 0011, ..., 1110, 1111),你会怎么写? 如果把固定4位变成任意n位,你又会怎么写?我知道那些会写高精度加法的人会跳出来说,就做一个高精度的二进制加法,Array的每一位保存二进制数的每一位,每次在末尾加1,然后让高精度加法自己处理进位,最后打印结果.老实说,我也做过这种蠢事,直到我在高中的一次竞赛中看到了一种比较巧妙的做法:(我最近一年都是写JavaScript,所以我在这里就

python实现的解析crontab配置文件代码_python

#/usr/bin/env python #-*- coding:utf-8 -*- """ 1.解析 crontab 配置文件中的五个数间参数(分 时 日 月 周),获取他们对应的取值范围 2.将时间戳与crontab配置中一行时间参数对比,判断该时间戳是否在配置设定的时间范围内 """ #$Id $ import re, time, sys from Core.FDateTime.FDateTime import FDateTime def

基于jquery拆分姓名的方法[纯javascript版]

之前已经分享过一个在dom中用户输入姓名后自动用js拆分成姓与名到表单中的jquery插件,由于项 目的需要,需要一个在客户端自动拆分,但不需要将拆分结果呈现给用户的方法,所以又写了一个独立的 方法,贴出来跟大家分享交流 $.extend({ splitName: function(fullname){ var hyphenated = ['欧阳','太史','端木','上官','司马','东方','独孤','南宫','万俟','闻人','夏侯','诸葛','尉迟','公羊','赫连','澹台'

基于jquery实现拆分姓名的方法(纯JS版)_jquery

之前已经分享过一个在dom中用户输入姓名后自动用js拆分成姓与名到表单中的jquery插件,由于项目的需要,需要一个在客户端自动拆分,但不需要将拆分结果呈现给用户的方法,所以又写了一个独立的方法,贴出来跟大家分享交流 复制代码 代码如下: $.extend({ splitName: function(fullname){ var hyphenated = ['欧阳','太史','端木','上官','司马','东方','独孤','南宫','万俟','闻人','夏侯','诸葛','尉迟','公羊',

自然数M拆分为连续自然数之和

有些数可以写成连续N(>1)个自然数之和,比如14=2+3+4+5:有些不能,比如8.那么如何判断一个数是否可以写成连续N个自然数之和呢?这是这一节的基本问题. 一个数M若可以写成以a开头的连续n个自然数之和,则M=a+(a+1)+(a+2)+-+(a+n-1)=n*a+n*(n-1)/2,要求a!=0,否则就是以a+1开头的连续n-1个整数了,也就是要求(M-(n+n*(n-1)/2))%n==0,即(M-(n*(n+1)/2))%n==0,这样就很容易判断一个数可不可以写成连续n个自然数的形

一个很有用的自定义函数(判断自然数是否包含2的指定次幂)

函数 /*           Name :    Fun_WheIncluded           Function :   判断选定的数字是否在给定的整数中           可以知道任何一个自然数都可以拆分成若干个2的幂的和,如:                1 = 2^0                2 = 2^1                3 = 2^0 + 2^1                4 = 2^2                5 = 2^0 + 2^2   

系统架构-性能篇章2(系统拆分1)

系统为什么拆分? 系统做大了,并发量无法扛得住,如何做? 业务做复杂了,单个应用中不能个性化,如何做? 模块和逻辑对各类资源开销非常特殊,如何做? ...... 拆分.拆分.再拆分. 由 全世界用一个系统表达全世界所有的企业和公司的业务开始,注定系统做大后必然拆分的走向,也就是一个大力士无法完成成千上万群众所能做到的一件大事,高集 成度的硬件和软件解决方案,为传统企业提供较为完善的解决方案,并在这种程度上是可以节约成本,高端机和高端存储的解决方案,当达到一个成本的交叉点后,随着数据量以及并发量的

HPE终于鲤鱼翻身 拆分企业服务业务

在连续滑坡五年之后,HPE业务终于鲤鱼翻身,首见增长.历时多年的惠普复兴,在HPE终现曙光. 与此同时,领导HPE重建并走出低谷的惠特曼继续激光般专注不同的市场和客户需求,把业务拆分进行到底.HPE宣布拆分企业服务业务,与CSC合资组建全球企业服务新公司. 在刚刚结束的HPE财季Q2,HPE总收入127亿美元,比一年前增长1%,利润增长5%.如果汇率不变收入相当于增长5%. 首席执行官惠特曼对公司复兴非常振奋,她说:"今天的结果是我自2011年出任CEO以来最好的业绩.包括HPE业务收入年度同比

“.中国”域名今日正式拆分

本报讯(记者 王伶玲)记者今天上午获悉,根据5月29日发布的关于".中国"域名独立运营的公告显示,从今天起,".中国"域名将独立运营,注册"中文.中国"域名,获得相同"中文.CN"域名的政策将同时终止.这意味着,独立运营后,"中文.CN"将另行收费,注册成本有所提升. 据了解,".中国"域名价格为320元/个/年,10月29日前注册"中文.中国"域名,将同时获赠与之关