题目链接:http://codeforces.com/contest/1207/problem/C
思路:dp【i】【j】,i表示到第几根柱子,j表示管道的高度是高还是低,j为0表示低,1表示高。
当s【i】为0时:
1.如果建造低管道的话:可以从前一个位置高的往下建,也可以沿着前一个位置低的继续建造
2.如果建造高管道的话:可以沿前一个位置高的继续建,也可以从前一个位置低的往上键
状态转移方程为:
1.dp[i][0]=min(dp[i-1][1]+2*a+b,dp[i-1][0]+a+b);
2.dp[i][1]=min(dp[i-1][1]+a+2*b,dp[i-1][0]+2*a+2*b);
当s【i】或者s【i-1】为1时:
1.不能建低管道:
2.高管道与上面相同
状态转移方程:
2.dp[i][1]=min(dp[i-1][1]+a+2*b,dp[i-1][0]+2*a+2*b);
#include<string.h>
#include<algorithm>
#include<stdio.h>
#define ll long long
using namespace std;
char s[200010];
ll dp[200010][2];
int main()
{
ll n,a,b,t;
scanf("%I64d",&t);
while(t--)
{
scanf("%I64d%I64d%I64d%s",&n,&a,&b,s);
memset(dp,0x3f,sizeof(dp));
dp[0][0]=b;
for(ll i=1; i<=n; i++)
{
if((s[i]=='0'&&s[i-1]=='0')||i==n)
{
dp[i][0]=min(dp[i-1][1]+2*a+b,dp[i-1][0]+a+b);
}
dp[i][1]=min(dp[i-1][1]+a+2*b,dp[i-1][0]+2*a+2*b);
}
printf("%I64d\n",dp[n][0]);
}
}