Educational Codeforces Round 71 C. Gas Pipeline(贪心+模拟)

大致题意

这个题意不太好描述啊,直接看原作吧。

在这里插入图片描述

思路

然后就可以考虑将两段1的区间合并,中间的0的管道铺设方式改为1的铺设方式。实际变化如下图:
在这里插入图片描述横向的管道可以看作没有变化,不过0的铺设方式会多用两个长度为一的竖向管道,然后支撑管相当于在0铺设方式上删掉了竖向管道,增加了(i-pre-2)个长度为1的支撑管。所以用上述价格差判断一下是否要合并。如果要的话就直接把0改成1,方便后面无脑统计。最后如果1在边缘位置要剪掉1根竖向管道。

代码
#include<bits/stdc++.h>
using namespace std;
#define maxn 200005
#define maxm 1000006
#define ll long long int
#define INF 0x3f3f3f3f
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,r,l) for(int i=r;i>=l;i--)
#define mem(a) memset(a,0,sizeof(a))
#define sqr(x) (x*x)
#define inf (ll)2e18+1
int read(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
     while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
     return f*x;
}
int t,n,a,b;
char s[maxn];
int main()
{
    scanf("%d",&t);
    while(t--){
        scanf("%d%d%d",&n,&a,&b);
        scanf("%s",s+1);
        s[n+1]='0';
        inc(i,1,n)if(s[i]=='0'&&s[i-1]=='1'&&s[i+1]=='1')s[i]='1';
        //inc(i,1,n)printf("%c",s[i]);
        //printf("\n");
        int pre=0;
        inc(i,1,n){
            if(s[i]=='1'){
                if(pre==0){
                    pre=i;
                    continue;
                }
                if(i-pre>2){
                    ll cos1=1ll*(i-pre-2)*b;
                    ll cos2=2ll*a;
                    if(cos1<=cos2){
                        inc(j,pre+1,i-1)s[j]='1';
                    }
                }
                pre=i;
            }
        }
        int cnt1=0;
        int cc=0;
        bool flag=0;
        inc(i,1,n){
            if(s[i]=='1'){
                cnt1++;
                if(flag==0){
                    cc++;
                    flag=1;
                }
            }
            else flag=0;
        }
        //printf("%d  %d\n",cnt1,cc);
        int shu=cnt1+cc;
        ll ans=1ll*(2ll*shu+n+1-shu)*b;
        int heng=n+cc*2;
        if(s[1]=='1')heng--;
        if(s[n]=='1')heng--;
        ans+=1ll*heng*a;
        printf("%lld\n",ans);
    }
    return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值