题解:P1012 [NOIP 1998 提高组] 拼数

· · 题解

前置知识:

回到这题,想要多个数字拼起来最大,即拼接后的字典序最大(因为长度显然是固定的)。

s_i + s_j > s_j + s_i(i < j) 排序然后依次拼接就是字典序最大,证明如下:

现在唯一问题就是要证这个排序能得到最优解。

法一

假设前面的选完了,我们要在在后面选一个。肯定优先选字典序大的,但是长度不一样怎么办。

现在在我们考虑范围内的字符串,类似这样(相同颜色的字符串相等):

设两个字符串 ss + t,按照我们那个排序方式。

法二

如果没有排序完,一定存在 s_i + s_i + \cdots < s_{i+1} + s_{i+1} + \cdots

证明交换 s_i,s_{i+1} 不会更劣即可。

和法一末尾部分一样。

Code

我这证法还是太tang了,我是先转化排序条件,再证最优性。

建议去看看 喵仔牛奶 的题解喵。

#include <iostream>
#include <algorithm>
#include <string>

using namespace std;

int n;
string a[30];

bool cmp(string x, string y){
  return x + y > y + x;
}

int main(){
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cin >> n;
  for(int i = 1; i <= n; i++){
    cin >> a[i];
  }
  sort(a + 1, a + 1 + n, cmp);
  for(int i = 1; i <= n; i++){
    cout << a[i];
  }
  return 0;
}