AtCoder Beginner Contest 286 题目讲解
蒟蒻来讲题,还望大家喜。若哪有问题,大家尽可提!
Hello, 大家好哇!本初中生蒟蒻今天讲解一下AtCoder Beginner Contest 286的C题——Rotate and Palindrome
===========================================================================================
原题
Problem Statement
You are given a string S S S of length N N N. Let S i ( 1 ≤ i ≤ N ) S_{i} (1\leq i\leq N) Si(1≤i≤N) be the i i i-th character of S S S from the left.
You may perform the following two kinds of operations zero or more times in any order:
- Pay A A A yen (the currency in Japan). Move the leftmost character of S to the right end. In other words, change S 1 S 2 … S N S_{1}S_{2}…S_{N} S1S2…SN to S 2 … S N S 1 S_{2}…S_{N}S_{1} S2…SNS1.
- Pay B B B yen. Choose an integer i i i between 1 1 1 and N N N, and replace S i S_{i} Si with any lowercase English letter.
How many yen do you need to pay to make
S
S
S a palindrome?
Note:
Palindrome is a string
T
T
T is a palindrome if and only if the
i
i
i-th character from the left and the
i
i
i-th character from the right are the same for all integers
i
(
1
≤
i
≤
∣
T
∣
)
i(1\leq i\leq \left | T \right |)
i(1≤i≤∣T∣), where
∣
T
∣
\left | T \right |
∣T∣ is the length of
T
T
T.
Constraints
- 1 ≤ N ≤ 5000 1\leq N\leq 5000 1≤N≤5000
- 1 ≤ A , B ≤ 1 0 9 1\leq A,B\leq 10^9 1≤A,B≤109
- S S S is a string of length N N N consisting of lowercase English letters.
- All values in the input except for S S S are integers.
Input
The input is given from Standard Input in the following format:
N A B
S
Output
Print the answer as an integer.
Sample Input 1
5 1 2
rrefa
Sample Output 1
3
First, pay
2
2
2 yen to perform the operation of the second kind once: let
i
=
5
i=5
i=5 to replace
S
5
S_{5}
S5 with
e
e
e. S is now
r
r
e
f
e
rrefe
rrefe.
Then, pay
1
1
1 yen to perform the operation of the first kind once.
S
S
S is now refer, which is a palindrome.
Thus, you can make
S
S
S a palindrome for
3
3
3 yen. Since you cannot make
S
S
S a palindrome for
2
2
2 yen or less,
3
3
3 is the answer.
Sample Input 2
8 1000000000 1000000000
bcdfcgaa
Sample Output 2
4000000000
Note that the answer may not fit into a 32 32 32-bit integer type.
思路
本题也其实是一个暴力枚举,我们枚举每一次进行n次1操作(将S的第一个放入最后一个位置),对于每一次我们判断最少的花费即可。
最小的花费算法:
我们因为对于每一个操作了
1
,
2
,
.
.
.
,
n
1, 2, ..., n
1,2,...,n的
S
S
S,那么
S
S
S变成操作最少的回文串是
S
1
,
.
.
.
,
S
⌊
n
2
⌋
+
(
n
%
2
≠
0
)
,
S
⌊
n
2
⌋
,
S
⌊
n
2
⌋
−
1
,
.
.
.
,
S
1
S_{1}, ..., S_{\left \lfloor \frac{n}{2} \right \rfloor + (n \% 2 \neq 0)}, S_{\left \lfloor \frac{n}{2} \right \rfloor}, S_{\left \lfloor \frac{n}{2} \right \rfloor - 1}, ...,S_{1}
S1,...,S⌊2n⌋+(n%2=0),S⌊2n⌋,S⌊2n⌋−1,...,S1
就比如说:
对于字符串
a
b
c
d
a
abcda
abcda,它的最少操作的回文串是
a
b
c
b
a
abcba
abcba
因此,构造出回文串,在对于每一个字符进行比较计算即可!
代码
#include <bits/stdc++.h>
#define int long long //本题需要开long long!
using namespace std;
int n, a, b;
deque<char> past, match;
int cost()
{
//构造匹配的回文串
match.clear();
for (int i = 1; i <= n / 2 + (n & 1); i ++)
match.push_back(past[i]);
for (int i = n / 2; i >= 1; i --)
match.push_back(past[i]);
match.push_front('0');
//判断每一个字符是否相同,计算花费
int num = 0;
for (int i = 1; i <= n; i ++)
num += (bool(match[i] != past[i]) * b);
return num;
}
signed main()
{
cin.tie(0);
ios::sync_with_stdio(false);
cin >> n >> a >> b;
char input;
past.push_back('0');
for (int i = 1; i <= n; i ++)
cin >> input, past.push_back(input);
int ans = 1e18;
ans = min(ans, cost());
for (int i = 1; i <= n; i ++)
{
past.push_back(past[1]), past.pop_front();
past.pop_front();
past.push_front('0');
ans = min(ans, cost() + i * a);//不停枚举操作1,找最小值
}
cout << ans << endl;
return 0;
}
今天就到这里了!
大家有什么问题尽管提,我都会尽力回答的!最后,除夕夜祝大家新年快乐!
吾欲您伸手,点的小赞赞。吾欲您喜欢,点得小关注!