CF848A From Y to Y

题目概要

对于给定的一个长度为 n n n 的字符串,初始时,我们将它视作 n n n 个长度为 1 1 1 的字符串的可重集,然后重复下列操作 n − 1 n-1 n1 次:

  • 从这些字符串中任取两个字符串 s , t s,t s,t,将它们删除,将 s + t s+t s+t 加入集合。注意这里的 + + + 是指字符串拼接。

操作的成本被定义为 ∑ c ∈ { a , b , ⋯   , z } f ( s , c ) × f ( t , c ) \sum_{c\in\left\{\texttt{a},\texttt{b},\cdots,\texttt{z}\right\}}f\left(s,c\right)\times f\left(t,c\right) c{a,b,,z}f(s,c)×f(t,c),其中 f ( s , c ) f\left(s,c\right) f(s,c) 是字符 c c c s s s 中出现的次数。更通俗地说,每次操作的成本为每个小写字母在两个字符串中出现次数的积

现在给定一个非负整数 k ( 0 ⩽ k ⩽ 1 0 5 ) k\left(0\leqslant k\leqslant 10^5\right) k(0k105),请你构造一个不超过 1 0 5 10^5 105 个字符的可重集,使得操作成本的最小值为 k k k。可以证明,这样的解一定是存在的。

思路概述

我觉得话这一道题目就是一个简单的构造题目,随便取一段字符串来看看,就不难发现就是一个等差数列,所以说最小的合并应该就是按字典序排列以后的顺序合并。所以代码的结构差不多就是直接循环走一遍,然后如果可以输出就输出,不然就不输出。
然后我们证明一下:
考虑对于每一对 ( i , j ) \left(i,j\right) (i,j) 满足 s i = s j s_i=s_j si=sj 计算贡献,然后我们可以每次合并看一下,他到底想让我们干什么东西,所以不难得出:如果合并 s , t s,t s,t,本质就是计算有多少 ( x , y ) \left(x,y\right) (x,y) 满足 s x = t y s_x=t_y sx=ty。所以我们就可以等到两个东西合并后再计算答案。所以最后就跟上面的一样,就是贪心。

代码部分

#include<bits/stdc++.h>
using namespace std;
int k,f[10005];
char ans='a';
signed main()
{
	cin>>k;
	if(k==0) 
		cout<<ans;
	int i=1; 
	for(i=1;f[i-1]<=k;i++) 
	 	f[i]=f[i-1]+i;
	for(int j=i-1;j>=1;j--)
	{
    	while(k>=f[j])
		{
    		k-=f[j];
    		int t=j+1;   
    		while(t--) 
				cout<<ans;
    		ans++;
		}
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值