[贪心,dp] Educational Codeforces Round 71 (Rated for Div. 2) C. Gas Pipeline (1207C)
2 seconds
256 megabytes
standard input
standard output
You are responsible for installing a gas pipeline along a road. Let's consider the road (for simplicity) as a segment [0,n]
on OX axis. The road can have several crossroads, but for simplicity, we'll denote each crossroad as an interval (x,x+1) with integer x. So we can represent the road as a binary string consisting of n
characters, where character 0 means that current interval doesn't contain a crossroad, and 1 means that there is a crossroad.
Usually, we can install the pipeline along the road on height of 1
unit with supporting pillars in each integer point (so, if we are responsible for [0,n] road, we must install n+1 pillars). But on crossroads we should lift the pipeline up to the height 2
, so the pipeline won't obstruct the way for cars.
We can do so inserting several zig-zag-like lines. Each zig-zag can be represented as a segment [x,x+1]
with integer x consisting of three parts: 0.5 units of horizontal pipe + 1 unit of vertical pipe + 0.5 of horizontal. Note that if pipeline is currently on height 2, the pillars that support it should also have length equal to 2
units.

Each unit of gas pipeline costs us a
bourles, and each unit of pillar — b bourles. So, it's not always optimal to make the whole pipeline on the height 2
. Find the shape of the pipeline with minimum possible cost and calculate that cost.
Note that you must start and finish the pipeline on height 1
and, also, it's guaranteed that the first and last characters of the input string are equal to 0.
The fist line contains one integer T
(1≤T≤100) — the number of queries. Next 2⋅T
lines contain independent queries — one query per two lines.
The first line contains three integers n
, a, b (2≤n≤2⋅105, 1≤a≤108, 1≤b≤108
) — the length of the road, the cost of one unit of the pipeline and the cost of one unit of the pillar, respectively.
The second line contains binary string s
(|s|=n, si∈{0,1}, s1=sn=0
) — the description of the road.
It's guaranteed that the total length of all strings s
doesn't exceed 2⋅105
.
Print T
integers — one per query. For each query print the minimum possible cost of the constructed pipeline.
4
8 2 5
00110010
8 1 1
00110010
9 100000000 100000000
010101010
2 5 1
00
94
25
2900000000
13
The optimal pipeline for the first query is shown at the picture above.
The optimal pipeline for the second query is pictured below:

The optimal (and the only possible) pipeline for the third query is shown below:

The optimal pipeline for the fourth query is shown below:

题意:
给一个长度为n的01串,和建单位长度的管道的代价a和单位长度的柱子b的代价,有4种柱子,低管道代价为a+b,高管道代价为a+2*b,上升管道代价为2*a+b,下降管道代价为2*a+2*b,01串中1代表要建高管道,一段高管道前要建上升管道,后要建下降管道,如果一个地方既要上升管道有要下降管道,则那个地方必须为高管道,问建这个区域管道和柱子的最小代价
思路:
读入01串后给管道分类,低管道为0,高管道为1,上升管道为2,下降管道为3,如果这个管道既要上升又要下降,则必须建高管道,再提取出上升管道和下降管道(这里设i从0开始),注意到只能是中间的某些下降管道到下一个上升管道这段看要不要换成全部都是高管道来比较代价,注意题中规定第1个管道必定是低管道或上升管道,最后一个必定是下降管道或低管道,下面的每个格子代价计算的是格子左边柱子的代价和格子管道的代价,在第一次访问时i为偶数是上升管道,但前面没有下降管道,故要算建低管道的代价和上升管道的代价,在最后一次访问时i为奇数时下降管道,但后面没有上升管道了,故要算建下降管道和低管道的代价,如果在中间,由于管道有升就有降且必定先升再降,而且才0开始存上升下降位置,所以偶数位存上升管道,奇数位置存下降管道,如果现在这个管道是下降管道,have计算从下降管道到上升管道之间有多少个高度低管道注意这里要开long long,不然会溢出,在可以先下降在上升的管道区域要判断是否这样建还是不下降而是继续全建高管道,选一个代价小的建,用2*a-b>=have*b这个公式判断,它是这样推出来的,设1类为这一段建下降管道,低管道,上升管道,2类为这一段全建高管道,1类的代价为(4*a+3*b+have*(a+b)),2类代价为(have+2)*(a+2*b),可见1类和2类在have不同时代价不同,所以可以做差来比较它们的大小,即推出此公式如果现在这个是上升管道则只算高管道有多少,因为第一个上升管道代价第一次时已经算过了,而中间碰到下降管道时计算代价是下降管道+低管道+上升管道.还要判断如果没有上升和下降的管道则全建低管道,输出答案时最后一个管道的右边柱子的代价要加上
#include<bits/stdc++.h>
using namespace std;
const int amn=2e5+;
long long m[amn],jg[amn];
int main(){
long long T,n,a,b,st,ed,tp=;long long ans;char in;
ios::sync_with_stdio();
cin>>T;
while(T--){
tp=;
cin>>n>>a>>b;
st=-;ans=ed=;
for(int i=;i<n;i++){cin>>in;if(in=='')m[i]=;else m[i]=;}m[n]=;
for(int i=;i<n;i++){
if(m[i]==){
if(st==-)st=i-;
if(i>){
if(m[i-]==)m[i-]=;
else m[i-]=; ///如果这个管道既要上升又要下降,则必须建高管道
}
if(i+<n){
if(m[i+]==){m[i+]=;ed=i+;}
else m[i+]=; ///如果这个管道既要上升又要下降,则必须建高管道(其实这里不用判断,因为前面还没判断过,不可能有2,只可能时1或0
}
}
}
for(int i=;i<n;i++)
if(m[i]==||m[i]==)jg[tp++]=i;
for(int i=;i<tp;i++){ ///注意位置i从0开始哦! 注意题中规定第1个管道必定是低管道或上升管道,最后一个必定是下降管道或低管道,下面的每个格子代价计算的是格子左边柱子的代价和格子管道的代价,低管道a+b,高管道a+2*b,上升管道2*a+b,下降管道2*a+2*b
if(i==) ///在第一次访问时i为偶数是上升管道,但前面没有下降管道,故要算建低管道的代价和上升管道的代价
ans+=jg[i]*(a+b)+*a+b;
else if(i==tp-) ///在最后一次访问时i为奇数时下降管道,但后面没有上升管道了,故要算建下降管道和低管道的代价
ans+=(n--jg[i])*(a+b)+*a+*b;
if(i!=tp-){ ///如果在中间
if(i&){ ///由于管道有升就有降且必定先升再降,而且才0开始存上升下降位置,所以偶数位存上升管道,奇数位置存下降管道
long long have=jg[i+]-jg[i]-; ///have计算从下降管道到上升管道之间有多少个高度低管道注意这里要开long long,不然会溢出
if(*a-b>=have*b) ///在可以先下降在上升的管道区域要判断是否这样建还是不下降而是继续全建高管道,选一个代价小的建,用2*a-b>=have*b这个公式判断,它是这样推出来的,设1类为这一段建下降管道,低管道,上升管道,2类为这一段全建高管道,1类的代价为(4*a+3*b+have*(a+b)),2类代价为(have+2)*(a+2*b),可见1类和2类在have不同时代价不同,所以可以做差来比较它们的大小,即推出此公式
ans+=(have+)*(a+*b);
else
ans+=(*a+*b+have*(a+b));
}
else ///如果现在这个是上升管道则只算高管道有多少,因为第一个上升管道代价第一次时已经算过了,而中间碰到下降管道时计算代价是下降管道+低管道+上升管道
ans+=(jg[i+]-jg[i]-)*(a+*b);
}
}
if(tp==) ///如果没有上升和下降的管道则全建低管道
ans+=n*(a+b);
printf("%lld\n",ans+b); ///最后一个管道的右边柱子的代价要加上
}
}
/**
给一个长度为n的01串,和建单位长度的管道的代价a和单位长度的柱子b的代价,有4种柱子,低管道代价为a+b,高管道代价为a+2*b,上升管道代价为2*a+b,下降管道代价为2*a+2*b,01串中1代表要建高管道,一段高管道前要建上升管道,后要建下降管道,如果一个地方既要上升管道有要下降管道,则那个地方必须为高管道,问建这个区域管道和柱子的最小代价
读入01串后给管道分类,低管道为0,高管道为1,上升管道为2,下降管道为3,如果这个管道既要上升又要下降,则必须建高管道,再提取出上升管道和下降管道(这里设i从0开始),注意到只能是中间的某些下降管道到下一个上升管道这段看要不要换成全部都是高管道来比较代价,
注意题中规定第1个管道必定是低管道或上升管道,最后一个必定是下降管道或低管道,下面的每个格子代价计算的是格子左边柱子的代价和格子管道的代价,
在第一次访问时i为偶数是上升管道,但前面没有下降管道,故要算建低管道的代价和上升管道的代价,在最后一次访问时i为奇数时下降管道,但后面没有上升管道了,故要算建下降管道和低管道的代价,
如果在中间,由于管道有升就有降且必定先升再降,而且才0开始存上升下降位置,所以偶数位存上升管道,奇数位置存下降管道,
如果现在这个管道是下降管道,have计算从下降管道到上升管道之间有多少个高度低管道注意这里要开long long,不然会溢出,在可以先下降在上升的管道区域要判断是否这样建还是不下降而是继续全建高管道,选一个代价小的建,用2*a-b>=have*b这个公式判断,它是这样推出来的,设1类为这一段建下降管道,低管道,上升管道,2类为这一段全建高管道,1类的代价为(4*a+3*b+have*(a+b)),2类代价为(have+2)*(a+2*b),可见1类和2类在have不同时代价不同,所以可以做差来比较它们的大小,即推出此公式
如果现在这个是上升管道则只算高管道有多少,因为第一个上升管道代价第一次时已经算过了,而中间碰到下降管道时计算代价是下降管道+低管道+上升管道.
还要判断如果没有上升和下降的管道则全建低管道,
输出答案时最后一个管道的右边柱子的代价要加上
**/
[贪心,dp] Educational Codeforces Round 71 (Rated for Div. 2) C. Gas Pipeline (1207C)的更多相关文章
- Educational Codeforces Round 71 (Rated for Div. 2)-F. Remainder Problem-技巧分块
Educational Codeforces Round 71 (Rated for Div. 2)-F. Remainder Problem-技巧分块 [Problem Description] ...
- Educational Codeforces Round 71 (Rated for Div. 2)-E. XOR Guessing-交互题
Educational Codeforces Round 71 (Rated for Div. 2)-E. XOR Guessing-交互题 [Problem Description] 总共两次询 ...
- Educational Codeforces Round 71 (Rated for Div. 2) Solution
A. There Are Two Types Of Burgers 题意: 给一些面包,鸡肉,牛肉,你可以做成鸡肉汉堡或者牛肉汉堡并卖掉 一个鸡肉汉堡需要两个面包和一个鸡肉,牛肉汉堡需要两个面包和一个 ...
- Educational Codeforces Round 71 (Rated for Div. 2)
传送门 A.There Are Two Types Of Burgers 签到. B.Square Filling 签到 C.Gas Pipeline 每个位置只有"高.低"两种状 ...
- Educational Codeforces Round 71 (Rated for Div. 2)E. XOR Guessing
一道容斥题 如果直接做就是找到所有出现过递减的不同排列,当时硬钢到自闭,然后在凯妹毁人不倦的教导下想到可以容斥做,就是:所有的排列设为a,只考虑第一个非递减设为b,第二个非递减设为c+两个都非递减的情 ...
- Educational Codeforces Round 71 (Rated for Div. 2) E XOR Guessing (二进制分组,交互)
E. XOR Guessing time limit per test1 second memory limit per test256 megabytes inputstandard input o ...
- [暴力] Educational Codeforces Round 71 (Rated for Div. 2) B. Square Filling (1207B)
题目:http://codeforces.com/contest/1207/problem/B B. Square Filling time limit per test 1 second mem ...
- Remainder Problem(分块) Educational Codeforces Round 71 (Rated for Div. 2)
引用:https://blog.csdn.net/qq_41879343/article/details/100565031 下面代码写错了,注意要上面这种.查:2 800 0,下面代码就错了. ...
- XOR Guessing(交互题+思维)Educational Codeforces Round 71 (Rated for Div. 2)
题意:https://codeforc.es/contest/1207/problem/E 答案guessing(0~2^14-1) 有两次机会,内次必须输出不同的100个数,每次系统会随机挑一个你给 ...
随机推荐
- Yuur persistent XSS
XSS发生在评论处/帖子正文处 index.php:37-38行 $sql="insert into topic set tid='$tid',title='$title',nickname ...
- Internet上的音频/视频概述
Internet上的音频/视频概述 计算机网络最初是为传送数据信息设计的.因特网 IP 层提供的"尽最大努力交付"服务,以及每一个分组独立交付的策略,对传送数据信息也是很合适的. ...
- FPGA小白学习之路(2)error:buffers of the same direction cannot be placed in series
锁相环PLL默认输入前端有个IBUFG单元,在输出端有个BUFG单元,而两个BUFG(IBUFG)不能相连,所以会报这样的错: ERROR:NgdBuild:770 - IBUFG 'u_pll0/c ...
- AI:拿来主义——预训练网络(一)
我们已经训练过几个神经网络了,识别手写数字,房价预测或者是区分猫和狗,那随之而来就有一个问题,这些训练出的网络怎么用,每个问题我都需要重新去训练网络吗?因为程序员都不太喜欢做重复的事情,因此答案肯定是 ...
- java基础进阶篇(二)_Arraylist ------【java源码栈】
前言 ArrayList 在开发中用到的频率很高,其中原生态提供的方法有一些很好用的重载版本,其中有的坑该跳得跳啊. 一.ArrayList的6种初始化方法1.构造方法 参数为空2.构造方法 参数为L ...
- 7-46 jmu-python-求单词长度 (10 分)
输入n个单词,计算每个单词长度.对单词长度排序,分行输出单词长度及其单词. 输入格式: 行1:单词个数n 分行输入n个单词 输出格式: 分行输出单词长度及其单词.(单词长度,单词)用元组表示 输入样例 ...
- YAML语法使用,JSR303数据校验
YAML YAML是 "YAML Ain't a Markup Language" (YAML不是一种置标语言)的递归缩写 # yaml配置 server: prot: YAML语 ...
- PC端如何下载B站里面的视频?
此随笔只是记录一下: PC端下载B站的视频,在blibli前面加上一个i 然后在视频上鼠标右键,视频另存为+路径即可 PS:网上其他的方法,比如在blibli前面加上kan,后面加上jj等,这些方 ...
- 微信小程序结构目录、配置介绍、视图层(数据绑定,运算,列表渲染,条件渲染)
目录 一.小程序结构目录 1.1 小程序文件结构和传统web对比 1.2 基本的项目目录 二.配置介绍 2.1 配置介绍 2.2 全局配置app.json 2.3 page.json 三.视图层 3. ...
- Linux系统简单文件操作命令
项目 内容 作业课程归属 班级课程链接 作业要求 作业要求链接 学号-姓名 17041419-刘金林 作业学习目标 1)学习Linux的基本操作命令:2)在终端上运用命令行去实现基本文件操作 1.查看 ...