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;
    }
    
    
  • 相关阅读:
    XmlDocument.selectNodes() and selectSingleNode()的xpath的学习资料
    config相关操作(转)
    网站存储session的方案
    VS2015 C#6.0 中的那些新特性(转自http://www.cnblogs.com/henryzhu/p/new-feature-in-csharp-6.html)
    ERROR L105: PUBLIC REFERS TO IGNORED SEGMENT 的解决办法
    关于C51内的code,idata,xdata
    KeilC51使用详解 (三)
    KeilC51使用详解 (二)
    KeilC51使用详解 (一)
    变量初始化
  • 原文地址:https://www.cnblogs.com/littleseven777/p/11845641.html
Copyright © 2011-2022 走看看