链接
http://codeforces.com/contest/998/problem/C
题目大意
给你一串只有 0 0 和组成的序列,你可以反转子串(连续),花费为 x x ,或者把一段连续的涂成 1 1 ,花费为,问你把所有的数字都变成 1 1 的最小花费
题解
当时打比赛的时候我想的已经很接近了,正解如下:
显然连续的或者连续的
1
1
我们拆开它是只会徒增花费,因此把相邻的变成一个,开头和结尾的可以去掉,最终变成010101010101010,消掉一个
0
0
有两种途径,要么,要么
set
s
e
t
,而且任何一个
0
0
都一定能通过这两种途径之一消掉,比如01010我给他,就成了
10010
10010
,也就相当于
010
010
,笑掉了一个
0
0
,即更好理解了。
但最后一个
0
0
必须要通过消掉,假设等价变形后有
p
p
个,则答案为
代码
#include <cstdio>
#include <algorithm>
#define ll long long
#define maxn 300010
using namespace std;
ll a[maxn], n, x, y;
ll read(ll x=0)
{
char c;
for(c=getchar();c<48 or c>57;c=getchar());
for(;c>=48 and c<=57;c=getchar())x=(x<<1)+(x<<3)+c-48;
return x;
}
ll readnumber()
{
char c;
for(c=getchar();c<48 or c>57;c=getchar());
return (ll)(c-48);
}
int main()
{
ll i, cnt=0, ans;
n=read(), x=read(), y=read();
for(i=1;i<=n;i++)a[i]=readnumber();a[0]=1;
for(i=1;i<=n;i++)if(!a[i] and a[i]!=a[i-1])cnt++;
if(cnt)ans=(cnt-1)*min(x,y)+y;
else ans=0;
printf("%I64d",ans);
return 0;
}