[CF1511D] Min Cost String 的题解
题目大意
现在需要使用从小写字母 \(a\) 开始的 \(k\) 种字符,构造一个长度为 \(n\) 的字符串 \(s\),使满足 \(i,j\in[1,n-1],i\neq j\) 且 \(a_i=a_j,a_{i+1}=a_{j+1}\) 的数对的数量最少。
其中 \(1\le n \le 2\times 10^5,1\le k \le 26\)。
思路
在使用 \(k\) 总字符的情况下,可以构造长度为 \(2\) 的字符串的种类为 \(\operatorname{A}^2_k\)。
但是因为在构造时上一队的字符会和这一对的字符组成以前出现过的字符。
为了避免这个情况,我们可以规定每一对里两个字母 \(s_i\) 和 \(s_{i+1}\) 满足 \(s_i < s_{i+1}\),所以当与上一组组合时就一定会满足 \(s_{i-1}>s_i\) 自然就不会出现重复的情况。
因为在如果所有的 \(s_i\) 都小于 \(s_{i+1}\) 时,我们就会漏掉一种 \(s_i=s_{i+1}\) 的情况,所以就需要特别的在每一个 \(s_i+1=s_{i+1}\) 的前面添加一个 \(s_i\)。
因为 \(\sum_{i=1}^k 2\times(k-i) +1\)
\(=\sum_{i=1}^k 2\times k-2\times i+1\)
\(= 2\times k^2-2\times \frac{k\times (1+k)}{2}+k\)
\(=2\times k^2 -k-k^2+k\)
\(=k^2\)
所以,使用以上方法构造的没有重复的序列最长为 \(k^2\)。
假设第 \(i\) 组字符串出现的次数为 \(cnt_i\),那么一定满足 \(\sum_{i=1}^{k^2} cnt_i\) 是一定的。
代价为
要使 \(cost\) 最小,那么所有的 \(cnt_i\) 应该越相近越小,所以在 \(n>k^2\) 的时候就应该将原来长度为 \(k^2\) 的字符串在后面进行重复。
直接模拟上面的操作,时间复杂度为 \(O(m)\)。
AC Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=2e5+5;
int n,m,cnt,a[30][30];
void solve(){
cin>>n>>m;
while(cnt<n){
for(int i=0;i<m;i++){
if(cnt>=n) break;
putchar('a'+i);
cnt++;
for(int j=i+1;j<m;j++){
if(cnt>=n) break;
putchar('a'+i);
cnt++;
if(cnt>=n) break;
putchar('a'+j);
cnt++;
if(cnt>=n) break;
}
}
}
}
signed main(){
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T=1;
while(T--) solve();
return 0;
}