看到一种解法,就跑 10 次往前插最优的,然后最前面就只需要放最小的。正确性如何证明?
int n, k;
cin >> n >> k;
vector<string> v(n);
for (int i = 0; i < n; i++) cin >> v[i];
string mn = *min_element(v.begin(), v.end());
if (k == 1) {
cout << mn;
return 0;
}
string ans, temp;
auto cmp = [&](string a, string b) -> bool {
string a1 = a + ans;
string b1 = b + ans;
return a1 <= b1;
};
for (int i = 0; i < min(10ll, k); i++) {
sort(v.begin(), v.begin() + n, cmp);
ans = v[0] + ans;
temp = v[0];
}
for (int i = 0; i < k - 10; i++) cout << temp;
cout << ans;
我的理解是,官解证明了答案一定是 smin 无限复制的前缀,于是答案最终由 smin 复制若干遍。最后选出一些串构成 smin 的前缀。因为长度不超过 10,所以跑 10 遍一定可以找到前缀。
但是不理解倒着跑为啥一定对?