Codeforces Round #493 (Div. 2) C. Convert to Ones 乱搞_构造_好题

本文探讨了一种算法,用于解决将01串转换为全1串的最小花费问题。通过分析操作类型和成本,提出了有效的解决方案,利用特定的划分和交换策略,实现了最优路径的寻找。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题意:
给你一个长度为 nnn010101串 ,你有两种操作:

1.将一个子串翻转,花费 XXX

2.将一个子串中的0变成1,1变成0,花费 YYY

求你将这个01串变成全是1的串的最少花费。

首先,我们可以将串按照0,10,10,1这划分,例如:
«00011001110»−>«000»+«11»+«00»+«111»+«0»«00011001110» -> «000» + «11» + «00» + «111» + «0»«00011001110»>«000»+«11»+«00»+«111»+«0»,可以看出只有相邻的010101串间进行操作才是有意义的。
将左面的 000 串与右面的 111 进行 “交换” 有两种办法:
1.将000 同一修改为 111.
2.将该串与靠右的一个111串交换(即翻转).
由于题中X,YX,YX,Y 是一个确定的值,这就使得我们每次的交换方法一定是相同的。然而,如果一直用第 222 种方法进行变换,最终必定还要使用一次 111 操作来将已经连城的一排 000, 统一修改为 111。即最小花费为:(p−1)∗min(x,y)+y(p-1)*min(x,y)+y(p1)min(x,y)+yppp 为原序列中 000 串的数量。

Code:

#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn = 300000 + 4;
int nex[maxn];
char str[maxn];
int main()
{
    int n, x, y, cnt = 0;
    scanf("%d%d%d",&n,&x,&y);
    scanf("%s",str + 1);
    str[0] = str[1] == '1' ? '0' : '1'; 
    for(int i = 1;i <= n; ++i) 
        if(str[i] == '0' && str[i] != str[i - 1]) ++cnt;
    if(cnt == 0) printf("0");
    else cout << (long long)(cnt - 1) * min(x, y) + y;
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值