CF447B DZY Loves Strings 题解

Content

有一个长度为 \(n\) 的仅含小写字母的字符串 \(s\) 以及 26 个英文小写字母的价值 \(W_\texttt{a},W_\texttt{b},...,W_\texttt{z}\),请求出在后面插入 \(k\) 个小写字母后所能够获得的最大价值。

对于一个长度为 \(x\) 的字符串 \(s'\),它的价值为 \(\sum\limits_{i=1}^x i\times W_{s'_i}\)

数据范围:\(1\leqslant n\leqslant 1000,0\leqslant k\leqslant 1000,0\leqslant W_{\texttt{a}\sim\texttt{z}}\leqslant 1000\)

Solution

没插入前的 \(s\) 的价值很好算,直接按照题目要求加就好了。

至于插入后的就要看字母价值中最大的那个了,因为根据样例来看,这道题是允许你重复加入同样的小写字母,所以我们找到最大的字母价值然后再插入 \(k\) 次,注意,插入的字母位置是从 \(n+1\) 标号到 \(n+k\) 的,所以通过等差数列求和公式可得插入后的字符的总价值为 \(\dfrac{(n+1+n+k)\times k\times\max\{W_{\texttt{a}\sim\texttt{z}}\}}{2}=\dfrac{(2n+k+1)\times k\times\max\{W_{\texttt{a}\sim\texttt{z}}\}}{2}\)

最后将插入的字符的价值加入到原来的价值里面就是我们想要的答案了。

Code

#include <cstdio>
#include <algorithm>
#include <cmath>
#include <iostream>
#include <cstring>
using namespace std;

string s;
long long k, val[27], maxi, ans;

int main() {
	cin >> s;
	scanf("%d", &k);
	for(int i = 1; i <= 26; ++i) {scanf("%d", &val[i]); maxi = max(maxi, val[i]);}
	long long len = s.size();
	for(long long i = 0; i < len; ++i) ans += (i + 1) * val[s[i] - 'a' + 1];
	ans += (2 * len + k + 1) * k * maxi / 2;
	printf("%lld", ans);
	return 0;
}
//貌似不需要开 long long(
posted @ 2021-12-17 14:17  Eason_AC  阅读(66)  评论(0)    收藏  举报