题目传送门
思路
这道题第一眼肯定会想到 dp 。
这题在不需通车的地方可以保持 2 2 2 的高度,也可以下降变成 1 1 1。
那么我们分类讨论一下,发现可以用二维 dp 来实现,第一层表示低,第二层表示高。
设 d p i , 0 / 1 dp_{i,0/1} dpi,0/1 为到这个位置的最小费用, 0 0 0 表示低, 1 1 1 表示高。
状态转移方程就是:当他为低的时候,$dp_{i+1,0} = min(dp_{i-1,0}+ a + 2b) ; ; ;dp_{i+1,1} = min(dp_{i-1,0}+ a ,dp_{i,1}) + a + 2b $。
当他为高的时候,$dp_{i+1,0} = 10^{18} ; ; ;dp_{i+1,1} = dp_{i,1} + a + 2b $。
最后输出 d p n , 0 dp_{n,0} dpn,0。
代码
#include<bits/stdc++.h>
using namespace std;
#define int long long
int t,n,a,b;
int x[200005],dp[200005][2];
string s;
void solve(){
int ans=0,cnt=0;
bool f=0;
cin>>n>>a>>b>>s;
for(int i=0;i<n;i++){
x[i]=(s[i]-'0');
}
dp[0][0]=b;
dp[0][1]=1e18;
for(int i=0;i<n;i++){
if(x[i]==0){
dp[i+1][0]=min(dp[i][0],dp[i][1]+a)+a+b;
dp[i+1][1]=min(dp[i][0]+a,dp[i][1])+a+2*b;
}else{
dp[i+1][1]=dp[i][1]+a+2*b;
dp[i+1][0]=1e18;
}
}
cout<<dp[n][0]<<endl;
}
signed main(){
cin>>t;
while(t--){
solve();
}
return 0;
}