B. Maximum Cost Deletion
You are given a string s s s of length n n n consisting only of the characters 0 and 1.
You perform the following operation until the string becomes empty: choose some consecutive substring of equal characters, erase it from the string and glue the remaining two parts together (any of them can be empty) in the same order. For example, if you erase the substring 111 from the string 111110, you will get the string 110. When you delete a substring of length l l l, you get a ⋅ l + b a \cdot l + b a⋅l+b points.
Your task is to calculate the maximum number of points that you can score in total, if you have to make the given string empty.
Input
The first line contains a single integer t t t ( 1 ≤ t ≤ 2000 1 \le t \le 2000 1≤t≤2000) — the number of testcases.
The first line of each testcase contains three integers n n n, a a a and b b b ( 1 ≤ n ≤ 100 ; − 100 ≤ a , b ≤ 100 1 \le n \le 100; -100 \le a, b \le 100 1≤n≤100;−100≤a,b≤100) — the length of the string s s s and the parameters a a a and b b b.
The second line contains the string s s s. The string s s s consists only of the characters 0 and 1.
Output
For each testcase, print a single integer — the maximum number of points that you can score.
Example
input
3
3 2 0
000
5 -2 5
11001
6 1 -4
100111
output
6
15
-2
Note
In the first example, it is enough to delete the entire string, then we will get 2 ⋅ 3 + 0 = 6 2 \cdot 3 + 0 = 6 2⋅3+0=6 points.
In the second example, if we delete characters one by one, then for each deleted character we will get ( − 2 ) ⋅ 1 + 5 = 3 (-2) \cdot 1 + 5 = 3 (−2)⋅1+5=3 points, i. e. 15 15 15 points in total.
In the third example, we can delete the substring 00 from the string 100111, we get 1 ⋅ 2 + ( − 4 ) = − 2 1 \cdot 2 + (-4) = -2 1⋅2+(−4)=−2 points, and the string will be equal to 1111, removing it entirely we get 1 ⋅ 4 + ( − 4 ) = 0 1 \cdot 4 + (-4) = 0 1⋅4+(−4)=0 points. In total, we got − 2 -2 −2 points for 2 2 2 operations.
简述题意
题外话,最近GM强度有点大,几天没有更新博客了,今天来水水(不是)
我们可以从长度为 N N N的字符串中删除连续的字符串,同时使结果加上 a ∗ l + b a * l + b a∗l+b
求最后如果想要把字符串所有字符全部删除后,得到的最大分数
解题思路
看到这一题的第一反应,可能感觉既要考虑a的正负、b的正负,还要比对 a , b a,b a,b的大小关系
但是本质上可没有这么复杂
因为对我们可以发现不管怎么删除字符串最终 ∑ 每个部分的字符串 ∗ a \sum 每个部分的字符串 * a ∑每个部分的字符串∗a都是 a ∗ s . s i z e ( ) a * s.size() a∗s.size()
所以说我们只需要考虑后半部分 b b b的正负
如果发现 b > = 0 b >= 0 b>=0的话,说明我们尽可能的增加 b b b的数量,即一个一个字符删除
如果发现 b < 0 b < 0 b<0,我们需要统计连续01的块数,将每一部分的 a ∗ l + b a * l + b a∗l+b
C o d e Code Code
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
#define all(x) begin(x),end(x)
#define str string
const int INF = 0x3f3f3f3f,N = 200010;
inline void solve() {
int n,a,b,ans = 0; cin >> n >> a >> b;
str s; cin >> s; int sz = s.size();
vector<int> res;
if(n == 1) return cout << a + b << endl,void();
//统计这一部分在i = j折了好几次
for(int i = 0,j = sz - 1;i <= j;) {
char c = s[i]; int cnt = 0;
while(i <= j && s[i] == c) {i++; cnt++;}
while(j >= i && s[j] == c) {j--; cnt++;}
res.push_back(cnt);
}
if(b >= 0) ans = sz * (a + b);
else {
for(auto it : res) {
ans += it * a + b;
}
}
cout << ans << endl;
}
int main(){
int t; cin >> t;
while(t--) solve();
// solve();
return 0;
}