题目链接: 链接
题意:给定一个01串 ,有两种操作。
第一种操作代价为X,可以翻转一个子串
第二种操作代价为Y,可以反转一个子串区间(子串的每个元素和1进行异或操作)
问把这个01串变成只有1的串所需的最小代价。
分析:
我们可以把给出的这个01串看成由1分隔的若干段0 ,
比如100010001111001000 可以看成是 0101010 ,
(最边上的1不用考虑,连续的1合并成1个 连续的0合并成1个)
因此,任何串都可以看成是若干段01 ,我们不妨设段数为num
我们把0101010的[2,3]翻转,得到0011010<=>01010 ,故而每次翻转都会减少一个0 。
策略:
假设先翻转m次,再把剩下的num-m个0反转成1 ,代价之和是
m * X+(num-m) * Y (0<=m<=num-1)
当X>=Y , m == 0时代价最小, 代价=num * y
当X<=Y , m == num-1 时代价最小 (num-1) * X + Y
#include<bits/stdc++.h>
using namespace std;
#define ll long long
const int maxn = 3e5+7;
const int mod = 1e9+7;
const ll inf = 34359738370;
int n,x,y;
char s[maxn];
int main()
{
scanf("%d %d %d",&n,&x,&y);
scanf("%s",s+1);
int num=0;
for(int i=1;i<=n;i++)
{
if(s[i]=='0')
{
num++;
while(i<n && s[i+1]=='0') i++;
}
}
if(!num)
{
puts("0");
return 0;
}
if(x>y) cout<<1ll*y*num;
else cout<<1ll*(num-1)*x+1ll*y;
return 0;
}