AtCoder Beginner Contest 286——C - Rotate and Palindrome

AtCoder Beginner Contest 286 题目讲解

A题 B题 C题 D题 E题


蒟蒻来讲题,还望大家喜。若哪有问题,大家尽可提!

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(1iN) 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} S1S2SN​ to S 2 ​ … S N ​ S 1 ​ S_{2}​…S_{N}​S_{1}​ S2SNS1.
  • 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(1iT), where ∣ T ∣ \left | T \right | T is the length of T T T.

Constraints

  • 1 ≤ N ≤ 5000 1\leq N\leq 5000 1N5000
  • 1 ≤ A , B ≤ 1 0 9 1\leq A,B\leq 10^9 1A,B109
  • 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,...,S2n+(n%2=0),S2n,S2n1,...,S1

就比如说:
对于字符串 a b c d a abcda abcda,它的最少操作的回文串是 a b c b a abcba abcba

因此,构造出回文串,在对于每一个字符进行比较计算即可!


代码

#include 
#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;
}

今天就到这里了!

大家有什么问题尽管提,我都会尽力回答的!最后,除夕夜祝大家新年快乐!
在这里插入图片描述

吾欲您伸手,点的小赞赞。吾欲您喜欢,点得小关注!

你可能感兴趣的:(算法-暴力,c语言,开发语言)