旅行 AA 算不清,几乎从来不是因为谁想占便宜,而是账太碎:
- 机票是一个人统一订的
- 民宿是另一个人付的,但有人晚到了一天
- 吃饭轮流买单,有一顿有人没去
- 酒水只有一半人喝
- 打车谁顺手谁付
回来一看,十几个人情账缠在一起。下面用一个完整例子走一遍。
一个例子:五个人,六笔账
A、B、C、D、E 五个人出去玩四天三晚。E 晚到一天,只住了两晚;C 不喝酒,也没去那个收费景点。
| 账目 | 谁付的 | 金额 | 算谁的 |
|---|---|---|---|
| 机票 | A | 5000 | 五人均分,各 1000 |
| 民宿 3 晚 | B | 2800 | 按人晚:ABCD 各 600,E 400 |
| 几顿饭 | C | 1500 | 五人均分,各 300 |
| 酒水 | D | 400 | 除 C 外四人,各 100 |
| 打车 | E | 300 | 五人均分,各 60 |
| 景点门票 | A | 800 | 除 C 外四人,各 200 |
民宿那一行值得多说一句:3 晚 × 4 人 + 2 晚 × 1 人 = 14 个人晚,2800 ÷ 14 = 每人晚 200。按人头均分的话 E 要摊 560,等于为一晚没住的房多付了 160。
笨办法:每笔账各转各的
最直觉的做法是每一笔都让参与的人转给付款人:机票 4 个人转给 A,民宿 4 个人转给 B,吃饭 4 个人转给 C……
这样算下来是 22 笔转账,而且 A 给 C 转、C 又给 A 转,互相抵消的钱来回走了好几趟。
正确的办法:先轧净额
对每个人算一个数:净额 = 自己垫付的 − 自己该摊的。
| 垫付 | 该摊 | 净额 | |
|---|---|---|---|
| A | 5800 | 2260 | +3540 |
| B | 2800 | 2260 | +540 |
| C | 1500 | 1960 | −460 |
| D | 400 | 2260 | −1860 |
| E | 300 | 2060 | −1760 |
正数是别人欠他的,负数是他欠别人的。所有人的净额加起来一定是 0:+3540 + 540 − 460 − 1860 − 1760 = 0。这是一个免费的校验,加起来不是 0,说明有一笔账记错了。
到这一步,谁欠谁的具体来源已经不重要了。D 欠的 1860 是欠「这个团」的,不是欠某个具体的人。
再配对:欠得最多的先还给被欠得最多的
- D 欠 1860,A 被欠 3540 → D 转 A 1860,A 还剩 1680 没收回
- E 欠 1760,A 还被欠 1680 → E 转 A 1680,A 清零,E 还欠 80
- C 欠 460,B 被欠 540 → C 转 B 460,B 还剩 80
- E 还欠 80 → E 转 B 80,全部清零
4 笔,结清。 22 笔变 4 笔。
为什么一定能在「人数 − 1」笔之内结清?每转一笔,至少有一个人的净额变成 0,五个人最多 4 笔就全清了。
这个算法的两个边界
它不保证是数学上最少的。 如果恰好有几个人的欠款加起来正好等于某一个人的应收(比如 D 和 E 加起来正好等于 A),本可以少转一笔,而按大小顺序配对的办法未必能找到这种组合。真正求「最少笔数」是一个组合搜索问题,人多了算不动。实践中贪心配对已经能把二十几笔压到四五笔,剩下那一笔的差别不值得在意。
它会改变「谁给谁转」。 上面例子里 C 的机票钱明明是 A 垫的,最后却转给了 B。有人会觉得别扭:「我欠的是 A,凭什么给 B」。这时候要解释的是:净额一样,转给谁都一样,每个人付出的总数和按笔转完全相同,只是少转了很多趟。
三个最常见的争执点
晚到早走。 住宿按人晚分,交通按实际乘坐的段分。原则是「没享受到的不摊」。
不喝酒、没去某个项目。 每一笔只摊给参与的人。不要事后在总账上「给他减个两百」:减多少说不清,而且会引出下一个人的「那我呢」。
零头。 100 元三个人分是 33.33 × 3 = 99.99,差 1 分。约定好让付款人或某个人吸收,保证每笔账各人摊的加起来恰好等于总额,否则净额加起来不是 0,最后总有人收不齐。
什么时候该用工具
两三个人、三五笔账,手算或者群里接龙就够了。下面几种情况建议用专门的分账工具:
- 人数 ≥ 4,或者账目超过十几笔
- 有人晚到、有人不喝酒,需要按笔调整参与人
- 有几笔是多个人凑钱付的
- 行程跨好几天,需要当天记、最后统一算
这时候工具的价值不在于算法有多高明,而在于每一笔当场记下来:付款人、金额、参与人三项当时都清楚,隔一天就开始模糊了。