From beginning till end, this message has been waiting to be conveyed.
For a given unordered multiset of n lowercase English letters ("multi" means that a letter may appear more than once), we treat all letters as strings of length1, and repeat the following operation n - 1 times:
- Remove any two elements s and t from the set, and add their concatenation s + t to the set.
The cost of such operation is defined to be , wheref(s, c) denotes the number of times characterc appears in string s.
Given a non-negative integer k, construct any valid non-empty set of no more than100 000 letters, such that the minimum accumulative cost of the whole process isexactly k. It can be shown that a solution always exists.
The first and only line of input contains a non-negative integer k (0 ≤ k ≤ 100 000) — the required minimum cost.
Output a non-empty string of no more than 100 000 lowercase English letters — any multiset satisfying the requirements, concatenated to be a string.
Note that the printed string doesn't need to be the final concatenated string. It only needs to represent an unordered multiset of letters.
12
abababab
3
codeforces
For the multiset {'a', 'b', 'a', 'b', 'a', 'b', 'a', 'b'}, one of the ways to complete the process is as follows:
- {"ab", "a", "b", "a", "b", "a", "b"}, with a cost of 0;
- {"aba", "b", "a", "b", "a", "b"}, with a cost of 1;
- {"abab", "a", "b", "a", "b"}, with a cost of 1;
- {"abab", "ab", "a", "b"}, with a cost of 0;
- {"abab", "aba", "b"}, with a cost of 1;
- {"abab", "abab"}, with a cost of 1;
- {"abababab"}, with a cost of 8.
The total cost is 12, and it can be proved to be the minimum cost of the process.
思路:首先给定一个字符串,无论怎么组合字符,代价都是固定的,也就是说字符串的代价与如何组合是没有关系的。
那么有关系的就是相同字符的个数,由此可以得到一递推公式:dp【i】=dp【i-1】+(i-1)
问题转化为从dp【i】中挑选n个数,使得n个数的和等于k。就直接从a字母开始累加,和超过k的时候退回字符,同时更新字符,继续累加。
#include<bits/stdc++.h>
using namespace std;
const int M=460;
int dp[M],sum;
char ans[1008610];
int main()
{
int k;
dp[0]=dp[1]=0;
for(int i=2; i<M; i++)
dp[i]=dp[i-1]+(i-1);
while(scanf("%d",&k)!=EOF)
{
if(k==0)
{
printf("a\n");
continue;
}
sum=0;
int cnt=0;
int len=0;
char T='a';
while(sum+dp[cnt]!=k)
{
ans[len++]=T;
if(sum+dp[++cnt]>k)
{
sum+=dp[cnt-1];
++T;///更新当前字符
len--;///退回字符
cnt=0;
}
}
ans[len]='\0';
puts(ans);
}
}