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;
    }
    
    
  • 相关阅读:
    制作Autorun的CD
    Sybase ASE MDA tables 装不上怎么办?
    对于TStringList.Find函数,我有话要说
    HH.exe CHM Operator Command.
    Delphi 7的一些常用的快捷键
    Explain Plan
    在Delphi中的Log
    subst windows下实用的磁盘映射工具
    Excel 2007 如何冻结多行&多列
    LinqToDataTable[转]
  • 原文地址:https://www.cnblogs.com/littleseven777/p/11845641.html
Copyright © 2011-2022 走看看