有错误请指出。
不太会用 Markdown,非常抱歉。
设数字字符串
x 的长度为
lx,其数值为
V(x)。
f(a,b)=V(a)⋅10lb+V(b)
a≻b⟺a+b>b+a
即:
V(a)⋅10lb+V(b)>V(b)⋅10la+V(a)
首先有这个:若
a≻b 且
b≻c,则
a≻c。
证明
由
a≻b 得
V(a)⋅10lb+V(b)>V(b)⋅10la+V(a).
移项:
V(a)(10lb−1)>V(b)(10la−1)变形为:
10la−1V(a)>10lb−1V(b) —— (1)
同理,由
b≻c 可得
10lb−1V(b)>10lc−1V(c) —— (2)
由 (1) 和 (2) 推出:
10la−1V(a)>10lc−1V(c)将其还原:
V(a)(10lc−1)>V(c)(10la−1) V(a)⋅10lc+V(c)>V(c)⋅10la+V(a) 即
a+c>c+a,也就是
a≻c,QED。
然后又有:按照上述规则排序得到的序列
S=s1s2…sn 一定是最大的。
证明,反证
假设存在一个最大整数的序列
T=a1a2…an,它不是按照我们定义的规则排序的。
既然它没按规则排,那么在
T 中一定至少存在一对相邻的数字
ai 和
ai+1,使得
ai+1≻ai,即
ai+1+ai>ai+ai+1。
现在,我们交换
ai 和
ai+1 的位置,得到新序列
T′。
-
在
T 中,拼接的结果是:
P+ai+ai+1+Q
-
在
T′ 中,拼接的结果是:
P+ai+1+ai+Q。
由于
ai+1ai>aiai+1,且这两个字符串前面和后面是完全一样的,因此
T′>T。
这与假设矛盾,QED。
就做完了。
怎么想到的
第一想法是按字典序排序嘛,数字比大小先比高位。
发现一个问题是,321 和 32 最后得出的数字是 32321,后者字典序小,反而在前面。
那改一下策略呢?先逐位比较,再判断长短。
但这种“打补丁”式的逻辑非常烧脑:如果多出的部分又是另一个数的前缀怎么办?递归下去逻辑会变得极其臃肿且容易出错。
回到问题的本质,比较最终数字的大小。
先考虑特殊的情况,两个字符串
a,b,拼成
ab 和
ba。
这里的关键直觉是如果
ab>ba,那么在最终的答案里,
a 就应该排在
b 的前面。
看看是否能推广到多个数。
尝试证明结论,就有了。