惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

美团技术团队
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
Martin Fowler
Martin Fowler
雷峰网
雷峰网
IT之家
IT之家
小众软件
小众软件
M
MIT News - Artificial intelligence
博客园 - 聂微东
J
Java Code Geeks
Blog — PlanetScale
Blog — PlanetScale
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
A
About on SuperTechFans
G
Google Developers Blog
Engineering at Meta
Engineering at Meta
Recent Announcements
Recent Announcements
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
The GitHub Blog
The GitHub Blog
F
Fortinet All Blogs
C
Check Point Blog
云风的 BLOG
云风的 BLOG
腾讯CDC
H
Help Net Security
Y
Y Combinator Blog
I
InfoQ

博客园 - 舒方小院

六一新玩具 some interesting words Linux下压缩不包含路径信息的压缩包 [ZzDW] 关于Java对象序列化您不知道的5件事 [ZzZz && momo] linux 误删 恢复rm -rf [转载] Windows如何在cmd命令行中查看、修改、删除与添加、设置环境变量 [转载] Linux的capability深入分析 [攻略转载] 在飞机上睡觉的七大攻略 [转载] ftp的模式ACTIVE&PASSIVE [转载] QQ黑名单 [转载] Eclipse快捷键 10个最有用的快捷键 [转载] Mysql常用命令行大全 [转载] php java交互 php/java bridge [转载] MySQL命令行下执行.sql脚本详解 [转载] rpm 常用命令 [转载] 控制寄存器(CR0,CR1,CR2,CR3,CR4) [转载] 汇编中AREA和ENTRY理解 [转载] Centos下如何解包rpm文件 生命期是个不可大意的问题
[原创] 算法题 Zero Sum的一种解法
舒方小院 · 2013-03-24 · via 博客园 - 舒方小院

今天丫头问了一道算法题:

Description:Consider the sequence of digits which contains N elements in increasing order (no duplicate element). If for each 2 digits, you can insert either a "+" for addition, or a "-" for subtraction, or a " " (space) to run the digits together. None of these operators can be added in front of the digit sequence. After each interval is implemented with either "+","-" or " "(space), calculate the result of the expression, if it is zero, then print the output.

There are possible 2 kinds of inputs:
1) The char 'S' (indicate sequential) followed by a simple digit number N, indicate that you are going to handle the sequence from 1 to N, 3<=N<=15. You need to find out all the possibility with the 3 operators and have the expression with sum as zero. For example: S3
2) The char 'R' (indicate randomized) followed by a sequential with comma separated. This sequence is already ordered ascending, and you must find out all the possibility with the 3 operators and have the expression with sum as zero. For example: R3,5,7,9

Sample Input:
S7

Expected Output:
(Format of output: sequence WITH operators (including space) with correct result, if more than 1 possibilities, output each of them with semicolon separated. If no possible operator vaues found, output a "NOTFOUND". If the input is illegal, output a "ILLEGAL")
1+2-3+4-5-6+7;1+2-3-4+5+6-7;1-2 3+4+5+6+7;1-2 3-4 5+6 7;1-2+3+4-5+6-7;1-2-3-4-5+6+7

Sample Input:
R3,5,7,9,11,13

Expected Output:
(Format of output: sequence WITH operators (including space) with correct result, if more than 1 possibilities, output each of them with semicolon separated, and ORDER by " ", then "+", then "-". If no possible operator vaues found, output a "NOTFOUND". If the input is illegal, output a "ILLEGAL")
3+5+7+9-11-13

大意是任意给一组依次增大的数,之间用"+", "-", 以及" "连接,其中" "运算有优先权,然后需要输出结果为0的组合。

思考了一下,大概可以这样做(以S7,即1234为例):

1. “ ”操作符优先级高于另外两个运算符,因此可以先算,以" "的位置不同,可以(2^(n-1))种组合方式(以下以&表示" "的位置):

1 2 3 4
1&2 3 4
1 2&3 4
1&2&3 4
1 2 3&4
1&2 3&4
1 2&3&4
1&2&3&4

从实践的角度,大可抛弃最后一种(蚊子也是肉)。

2. 由步骤1,我们得到了以下组合,然后其中的每一项都可以用"+"和"-"的枚举来计算:
1 2 3 4
12 3 4
1 23 4
123 4
1 23 4
12 34
1 234

3. 我们来看另一个问题,及几个数加减为0的问题:

假设有数a b c d,

a+b+c-d和-a-b-c+d在是否为0上的结果是一样的,
是不是有点遗憾?如果是a-b-c+d就好了。那么差别在哪里?对,加上这个2a就一样了。
也就是说,当我们计算出了a+b+c-d的值z时,我们只要算一下2a-z是否为0就知道a-b-c+d的值了。也就是说,对于
+++
++-
+-+
+--
-++
-+-
--+
---
我们只需计算
+++(不可能)
++-
+-+
+--
即可,这里,我们又可以光荣的去掉第一项(蚊子也是肉2),那么这一部分的计算量为(2^m/2-1)*(m+2)=(2^(m-1)-1)*(m+2),记为f(m),f(1)=0时,意为仅有两数,由于各数均不等,所以不用计算即可确定不可能,因此计算数为0也是合理的。
注:这里m+2是指对每次计算进行的m次的加减操作以及2*a-z进行的2次操作。

4. 我们来看一下计算量吧
1 2 3 4  m=3
12 3 4   m=2
1 23 4   m=2
123 4   m=1
1 23 4  m=2
12 34   m=1
1 234  m=1
1234 m=0(不可能)

归纳一下,总计算量为:C(n-1,0)f(n-1) + C(n-1,1)*f(n-1-1) + C(n-1,2)*f(n-1-2) + ... + C(n-1, n-2)f(1)
                               = C(n-1,0)f(n-1) + C(n-1,1)*f(n-1-1) + C(n-1,2)*f(n-1-2) + ... + C(n-1, n-3)f(2)

因此,n=4时,运算次数为C(3,0)f(3)+C(3,1)f(2) = f(3) + 3*f(2) = (2^2-1)*(3+2) + 3*(2^1-1)*(2+2) = 3*5+3*1*4 = 27