CodeForces - 998C - Convert to Ones -思维

题目链接

题目大意:

现在有一个长度为n的字符串 0 1,要将这个字符串全都弄成1,现在可进行两种操作,有两种花费,

分别是,花费x,将字符串中某一连续字符串顺序颠倒;花费y将字符串中某一连续字符串按位取反

 

思路:

任何一段0 1序列都可以看做是一串 0 然后用 1 切割开。首先,因为我们是要把目标串变成全1串,所以开头的1(和结尾的1)我们可以不去管它,所以我们可以把所有的串看做是这种(开头的1和结尾的1无所谓就全都省略)然后我们可以怎么做呢?例如:000 1000 10000 100 100这个串,因为上面操作的花费与段的长度无关,所以我们可以把相邻的1合成一个1,相邻的0合成一个0。所以原串就可以转化成  0 10 10 10 10。

假设0分成的段的数量是num。

第一种方法,我们可以选择第二段 10 ,对其进行倒置操作,所以整个串就变成了 0 01 10 10 10。然后再次合并相邻的1 和相邻的 0 ,原串变成了  0 10 10 10。然后在进行一次相同的操作,就变成了 0 10 10.以此类推,最后将变成 0 10,再倒置一次,变成 00 1,然后再对00 进行一次操作二即可。这种方法的花费为 (num-1)*x+y。

第二种方法,我们直接对每一段0实施操作二,使得其变为全1串,这样的花费是num*y。

所以显然,当x<=y时,我们选择第一种方案,当x>y时,我们选择第二中方案,统计0的段数,直接输出结果即可。

分析参考自:https://blog.csdn.net/weixin_42165981/article/details/81264009

大神的代码貌似写错了。。。

代码:

#include<iostream>
#include<cstdio>
#define maxn 300005
using namespace std;

char s[maxn];
int main()
{
    int n,x,y;
    cin>>n>>x>>y;
    cin>>s;
    int p=0;
    for(int i=0; i<n; i++)
        if(s[i]=='0')
            p++;
    if(p==0)
    {
        cout<<"0"<<endl;
        return 0;
    }
    long long ans=0;
    if(x>=y)
    {
        for(int i=1; i<n; i++)
        {
            if(s[i-1]=='0'&&s[i]=='1')
                ans+=y;
        }
        if(s[n-1]=='0')
            ans+=y;
        cout<<ans<<endl;
        return 0;
    }

    else
    {
        if(s[0]=='0')
            p=1;
        else
            p=0;
        for(int i=1; i<n; i++)
            if(s[i]=='0')
            {
                p++;
                if(p>1&&s[i-1]=='1')
                    ans+=x;
            }
        ans+=y;
        cout<<ans<<endl;
        return 0;
    }
    return 0;
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值