zoukankan      html  css  js  c++  java
  • CF 997A Convert to Ones

    CF997A Convert to Ones

    题目链接:【洛谷】 CF997A Convert to Ones

    算法标签: 字符串贪心模拟

    题目

    题目描述

    给你一个长度为 n 的01串($ n leq 3*10^5 $),你有两种操作:

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

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

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

    输入格式

    第一行,三个整数(n)(x)(y),分别代表字符串长度、翻转字串的花费、修改字串的花费。

    第二行,为一个长度为(n)的字符串。

    输出格式

    共一行,为所求的最小花费。

    输入输出样例

    输入 #1

    5 1 10
    01000
    

    输出 #1

    11
    

    输入 #2

    5 10 1
    01000
    

    输出 #2

    2
    

    输入 #3

    7 2 3
    1111111
    

    输出 #3

    0
    

    题解:

    想法很巧妙,可以定位为一道思维题,大致的思路就是贪心(不确定)。

    由于一个01串,假设为(011111000001) ,在这道题的题目下可以很简单的处理为(0101)这样一个串,在进行两种操作取最小值。

    仔细分析这两种操作的时候,我们可以得到以下结论:

    1 我们可以将所有中操作找出两种最优的:

    a. 将0放在一边,1放在一边,最终一次转换 
    
    b. 每一个都单独转换
    

    2 将字符串第0位设为一个1,这样我们只需要统计由某一位为0而前一位为1的个数,这样的答案就是操作的总次 数(可以推得无论如何进行操作总次数都一致)。而且我们可以发现无论如何进行操作,最后一次都是转换, 所以我们可以得出

    (ans = (cnt - 1) * min(x, y) + y;)

    由此此题得解,注意本题数据需要开long long。

    下面附上AC代码

    AC代码

    #include <bits/stdc++.h>
    
    using namespace std;
    
    const int N  = 300030;
    
    typedef long long ll;
    
    ll n, x, y, cnt;
    char num[N];
    
    int main()
    {
    	scanf("%d%d%d", &n, &x, &y);
    	scanf("%s", num + 1);
    	num[0] = '1';
    	for (int i = 1; i <= n; i ++ )
    	{
    		if (num[i] == '0' && num[i - 1] == '1')
    			cnt ++ ;
    	}
    	if (cnt == 0)
    		printf("0");
    	else
    	{
    		ll ans = (cnt - 1) * min(x, y) + y;
    		printf("%lld
    ", ans);
    	}
    	return 0;
    }
    
    
  • 相关阅读:
    http简单demo
    启迪思维:循环链表
    数据表行列转换
    防止短时间内重复提交表单数据js约束
    ASP.NET2.0文件上传以及图片处理
    支付宝倒计时代码
    js 定时刷新页面
    C# 将cookiecontainer写到本地
    用C#生成随机中文汉字验证码的基本原理
    删除指定文件夹里的所有文件
  • 原文地址:https://www.cnblogs.com/littleseven777/p/11845641.html
Copyright © 2011-2022 走看看