题目链接:https://vjudge.net/problem/CodeForces-1207C
题意:输入道路总长度,铺设一个单位的输油管或桥墩的价格,输入一个字符串代表高度,0代表高度为1,1代表高度为2,求最小价格。注意起点终点高度必须为1。
思路:先预处理出从当前位置开始往后有多少个和他相同的高度,然后遍历分情况讨论一下每阶段的花费即可。注意中间计算可能爆int。
#include<bits/stdc++.h>
using namespace std;
const int maxn=2e5+5;
char s[maxn];
long long cnt[maxn];
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
long long n,a,b;
memset(cnt,0,sizeof(cnt));
scanf("%lld%lld%lld",&n,&a,&b);
scanf("%s",s);
int l=strlen(s);
long long sum=0;
for(int i=l-2; i>=0; i--)//预处理当前位置往后有多少和它一样高度的
{
if(s[i]==s[i+1])
{
cnt[i]=cnt[i+1]+1;
}
else
{
cnt[i]=0;
}
}
bool flag=false;//判断当前建设高度 false为1,true为2
sum+=b;//最开始的一个桥墩
for(int i=0; i<l-1; i++)
{
if(s[i]=='0'&&s[i+1]=='1'&&!flag)//必须要上升到高度为2的情况
{
sum+=2*a+2*b;
flag=true;
continue;
}
if(flag)//当前高度为2
{
if(s[i]=='0')
{
long long cnt1=cnt[i]*(a+b)+2*a+b;//把高度降下来时的花费
if(cnt[i]+i<l-1)//相比不下降 如果下降高度并且后面还有高度为2的情况
//还需要再加上上升的花费
{
cnt1=cnt1+b+a;
}
long long cnt2=cnt[i]*(a+2*b)+a+2*b;//不下降时的花费
if(cnt[i]+i==l-1)//最后高度一定是1 连续到最后一位,必须要把高度降下来 相比下降高度
//不下降高度必须要额外加上下降的花费
{
cnt2=cnt2-b+a;
}
if(cnt1>=cnt2)
{
sum+=a+2*b;
}
else
{
sum+=2*a+b;
flag=false;
}
}
else//为1的情况
{
sum+=a+2*b;
}
}
else//当前高度不为2
{
sum+=a+b;
}
}
// 在最后一位判断高度是多少
if(flag)
{
sum+=2*a+b;
}
else
{
sum+=a+b;
}
printf("%lld\n",sum);
}
return 0;
}