目录
题面
可以在此阅读:
https://codeforces.com/problemset/problem/997/A
也可以看我的题面:
题目描述
You've got a string a1,a2,…,an , consisting of zeros and ones.
Let's call a sequence of consecutive elements ai,ai + 1,…, aj ( 1≤ i≤ j≤ n ) a substring of string a .
You can apply the following operations any number of times:
- Choose some substring of string a (for example, you can choose entire string) and reverse it, paying x coins for it (for example, «0101101» → «0111001»);
- Choose some substring of string a (for example, you can choose entire string or just one symbol) and replace each symbol to the opposite one (zeros are replaced by ones, and ones — by zeros), paying y coins for it (for example, «0101101» → «0110001»).
You can apply these operations in any order. It is allowed to apply the operations multiple times to the same substring.
What is the minimum number of coins you need to spend to get a string consisting only of ones?
输入格式
The first line of input contains integers n , x and y ( 1 ≤ n ≤ 300000,0≤x,y≤109 ) — length of the string, cost of the first operation (substring reverse) and cost of the second operation (inverting all elements of substring).
The second line contains the string a of length n , consisting of zeros and ones.
输出格式
Print a single integer — the minimum total cost of operations you need to spend to get a string consisting only of ones. Print 0 , if you do not need to perform any operations.
题意翻译
给你一个长度为 n 的01串( n≤3∗105 ),你有两种操作:
1.将一个子串翻转,花费 X
2.将一个子串中的0变成1,1变成0,花费 Y
求你将这个01串变成全是1的串的最少花费。
思路
我们可以将给出的字符串 edit 压缩一下,也就是将一段连续的相同字符压缩成一个这样的字符,比如将字符串 1000110 压缩成 1010。我们可以花费 x 元,执行一次翻转操作,也就是将压缩后的字符串中的一个 01 或 10 消掉。我们还可以花费 y 元,执行一次取反操作,也就是将压缩后的字符串中的一个 0 消掉。因此我们可以想到两种有可能是最优解的解法。
第一种解法:暴力取反
我们直接不考虑翻转操作,直接把字符串中所有 0 变成 1。这种操作花费 cnt×y 元,其中 cnt 表示压缩后的字符串中 0 的个数。
第二种解法:消消乐
我们先执行 cnt−1 次翻转操作,把压缩后的字符串变成 01 或 10,然后再执行一次取反操作,将压缩后的字符串中的 0 去掉。这种操作花费 (cnt−1)×x+y 元,其中 cnt 表示压缩后的字符串中 0 的个数。
答案
综上所述,答案为 cnt×y 与 (cnt−1)×x+y 中的最小值。
补充注意点
我们在统计压缩后的字符串中 0 的个数 cnt 时,还要查看一下 edit 中最后一个字符是否为 0,如果是,将 cnt 加 1。
特判
如果压缩后的字符串中 0 的个数为 0,表示没有 0,直接输出 0,因为不需要修改。
代码
#include<iostream>
#include<string>
using namespace std;
long long cnt,n,x,y;
string edit;
int main(){
cin>>n>>x>>y;
cin>>edit;
for(int i=0;i<edit.size();i++){
if(edit[i]=='0'&&edit[i+1]=='1'){
cnt++;
}
}
if(edit[edit.size()-1]=='0'){
cnt++;
}
if(cnt==0){
cout<<0;
}else{
cout<<min(cnt*y,(cnt-1)*x+y);
}
return 0;
}