链接
http://codeforces.com/contest/998/problem/C
题目大意
给你一串只有 和 组成的序列,你可以反转子串(连续),花费为 ,或者把一段连续的 涂成 ,花费为 ,问你把所有的数字都变成 的最小花费
题解
当时打比赛的时候我想的已经很接近了,正解如下:
显然连续的
或者连续的
我们拆开它是只会徒增花费,因此把相邻的变成一个,开头和结尾的
可以去掉,最终变成010101010101010,消掉一个
有两种途径,要么
,要么
,而且任何一个
都一定能通过这两种途径之一消掉,比如01010我给他
,就成了
,也就相当于
,笑掉了一个
,
即更好理解了。
但最后一个
必须要通过
消掉,假设等价变形后有
个
,则答案为
代码
#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;
}