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

推荐订阅源

Google DeepMind News
Google DeepMind News
Stack Overflow Blog
Stack Overflow Blog
Hugging Face - Blog
Hugging Face - Blog
博客园_首页
T
The Blog of Author Tim Ferriss
博客园 - 叶小钗
N
Netflix TechBlog - Medium
腾讯CDC
C
Check Point Blog
P
Proofpoint News Feed
Engineering at Meta
Engineering at Meta
GbyAI
GbyAI
S
SegmentFault 最新的问题
F
Fortinet All Blogs
美团技术团队
U
Unit 42
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 司徒正美
F
Full Disclosure
Recorded Future
Recorded Future
D
DataBreaches.Net
博客园 - 【当耐特】
Martin Fowler
Martin Fowler
J
Java Code Geeks
I
InfoQ
Y
Y Combinator Blog
A
About on SuperTechFans
AI
AI
爱范儿
爱范儿
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Forbes - Security
Forbes - Security
W
WeLiveSecurity
M
MIT News - Artificial intelligence
雷峰网
雷峰网
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
Simon Willison's Weblog
Simon Willison's Weblog
Schneier on Security
Schneier on Security
The GitHub Blog
The GitHub Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
aimingoo的专栏
aimingoo的专栏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
G
GRAHAM CLULEY
Know Your Adversary
Know Your Adversary
Latest news
Latest news
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
D
Docker
Recent Commits to openclaw:main
Recent Commits to openclaw:main
量子位
V2EX - 技术
V2EX - 技术
Project Zero
Project Zero

博客园 - 舒方小院

六一新玩具 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