Codeforces 998C Convert to Ones(思维)

C. Convert to Ones
题目大意:一个长度为n的01字符串,反转任何一个连续区间价值为x,将任意一个全为0的子区间改为1价值为y,求将字符串全变为1的最小价值。
这题也是看了好久才找到规律。
我们可以发现,若要用x操作,就是要把1通过反转连起来,那么剩下的0的子区间就用y操作。
那么要用多少次x操作呢,看似很难确定。。
设0的子区间个数为m,我们不难发现,将所有1连在一起需要m-1次x操作。
那么如果我们不执行m-1次x操作,设执行x操作a次(a<m-1),那么代价为a * x+(m-a) * y;
若x<y,那么则是a越大越好,那么a取m-1;
若x>y,就直接执行m次y操作价值会最小.
所以答案就是min((m-1) * x+y,m * y);
注意m==0时要特判。

 1 #include <iostream>
 2 #include <cstdio>
 3 #include <cstring>
 4 #include <algorithm>
 5 #include <cmath>
 6 #include <queue>
 7 #define ll long long
 8 #define out(a) printf("%lld",a)
 9 using namespace std;
10 int n,x,y;
11 ll cnt,ans;
12 char str[1][300050];
13 int read()
14 {
15     int s=0,t=1; char c;
16     while (c<‘0‘||c>‘9‘){if (c==‘-‘) t=-1; c=getchar();}
17     while (c>=‘0‘&&c<=‘9‘){s=s*10+c-‘0‘; c=getchar();}
18     return s*t;
19 }
20 int main()
21 {
22   n=read(); x=read(); y=read();
23   scanf("%s",str[0]);
24   for (int i=0;i<n;i++)
25     if (str[0][i]==‘1‘&&str[0][i-1]==‘0‘) cnt++;
26   if (str[0][n-1]==‘0‘) cnt++;
27   if (cnt==0) ans=0;
28   else ans=min((cnt-1)*x+y,cnt*y);
29   out(ans);
30   return 0;
31 }

原文地址:https://www.cnblogs.com/Kaleidoscope233/p/9277281.html

时间: 2024-11-11 04:43:40

Codeforces 998C Convert to Ones(思维)的相关文章

codeforces 848B Rooter&#39;s Song 思维题

http://codeforces.com/problemset/problem/848/B 给定一个二维坐标系,点从横轴或纵轴垂直于发射的坐标轴射入(0,0)-(w,h)的矩形空间.给出点发射的坐标轴,位置,延迟时间,发生碰撞则交换方向.求最后每个点的射出位置. 首先我们观察能得出两个结论,1. 类似蚂蚁爬树枝的问题,相遇只会交换方向,所以最后的射出点集只会因为碰撞而改变动点与射出点的对应关系,而不会增加减少射出点集.2.我们根据其射入位置和延迟时间可以计算出一个值v=pos-time,只有这

Codeforces 997A Convert to Ones(思维)

https://codeforces.com/problemset/problem/997/A 题目大意: 给定一串0-1序列,定义两种操作: 操作一:选取一连续串倒置. 操作二:选取一连续串把进行01互换(取反). 并给出操作一和操作二的代价,分别为x和y. 操作到最后要把串变成只含1的串,问最小的操作代价. 假定连续0的段数是num,那么可以知道,每进行一次操作一,就可以减少一次操作二的次数. 因此就要考虑操作一和二的优先使用问题: 如果x<y   就优先倒置,把所有0块区间合成一个0块区间

Codeforces 722C(并查集 + 思维)

题目链接:http://codeforces.com/problemset/problem/722/C 思路: 题目给的操作数从第 1 个到第 N 个数是删除原数组中的一个数, 那么反过来从后往前就是增加原数组中的一个数, 每增加一个值, 那么就有四种情况: 第一种和前后都不连续, 即自成一个集合; 第二种:和前面的数连续, 即和前一个数在一个集合; 第三种和之后一个数连续, 即和之后的一个数在一个集合; 第四种既和前面一个数连续也和后面一个数连续,那么说明前后两个集合被这个数合并成一个集合.

Educational Codeforces Round 26 D dp,思维

Educational Codeforces Round 26 D. Round Subset 题意:有 n 个数,从中选出 k 个数,要使这 k 个数的乘积末尾的 0 的数量最多. tags:dp好题 dp[i][j][l] 表示前 i 个数,选取了其中 j 个数,分解因子后有 l 个 5时,最多有多少个 2 .i 这一维明显可以省略. 这题一开始有个地方写挫了..选取 j 个数时,应该反着来,即 for( j, k, 1) ,不是 for( j, 1, k) ,不然会多算. #include

CodeForces 494A Treasure(字符串匹配 思维)

http://codeforces.com/problemset/problem/494/A 题意 有一串字符串由 ( ) # 组成 #代表若干个 ) 问#具体为多少时可以使每个( 都对应一个 ) 思路 由于可以有多种方式组合 可以默认前 cnt-1 个 #号 与它前一个 ( 匹配 之后再对最后一个#进行特判(分别判断 #右边的num1 和左边的num2 如果num2-num1>0 则满足) #include<cstdio> #include<cstring> #includ

codeforces 893D Credit Card 贪心 思维

codeforces 893D Credit Card 题目大意: 有一张信用卡可以使用,每天白天都可以去给卡充钱.到了晚上,进入银行对卡的操作时间,操作有三种: 1.\(a_i>0\) 银行会给卡充入\(a_i\)元 2.\(a_i<0\) 银行从卡中扣除\(a_i\)元 3.\(a_i=0\) 银行对你的卡进行评估,违背了规则就无权再使用此卡 规则1:卡内的余额不得超过\(d\)元 规则2:当\(a_i=0\)时,卡内的余额不能是负数 现在问为了维持信用的平衡,最少去银行几次.(去一次,充

codeforces 895B XK Segments 二分 思维

codeforces 895B XK Segments 题目大意: 寻找符合要求的\((i,j)\)对,有:\[a_i \le a_j \] 同时存在\(k\),且\(k\)能够被\(x\)整除,\(k\)满足:\[a_i \le k \le a_j\] 思路: 整体数组排序,对于当前\(a_i\)寻找符合条件的\(a_j\)的最大值和最小值 有:\[(a_i-1)/x+k=a_j/x\] 所以可以通过二分查找获得,这里我寻找\(((a_i-1)/x+k)*x\)为下界,\(((a_i-1)/x

CF1103C Johnny Solving (Codeforces Round #534 (Div. 1)) 思维+构造

题目传送门 https://codeforces.com/contest/1103/problem/C 题解 这个题还算一个有难度的不错的题目吧. 题目给出了两种回答方式: 找出一条长度 \(\geq \frac nk\) 的路径: 找出 \(k\) 个简单环,满足长度不是 \(3\) 的倍数,并且每个环至少存在一个点不在别的环中. 很显然题目并不是要你随便挑一种回答方式开始单独研究.最有可能的情况是两种回答方式可以替补. 如果我们随便作出原图的一棵生成树,如果最长的路径长度 \(\geq \f

CodeForces 1294D MEX maximizing(思维)

http://codeforces.com/contest/1294/problem/D 大致题意: 刚开始有一个空集合,会往里添加q次数,每次加一个值,而且你可以让这个数任意加减x若干次 每次添加后就查询当前最小的不属于这个集合的非负整数是什么.尽可能让这个最小的不属于这个数列的非负整数最大. 解题思路: 由于每次添加的数t可以加减任意次的x,故我们只需记录t%x,用num[i]表示i的个数 用ans去递增查询是否可以满足要求就行,如果num[ans%x]不为0,说明之前有一个没发挥作用的t可