Gas Pipeline CodeForces - 1207C(简单dp)

题目链接

https://codeforces.com/problemset/problem/1207/C

题意:

排水工人正在铺管道,其中0表示非十字路口,1表示十字路口,十字路口时管道下面柱子的高度是平时高度的2倍。计算铺完全程所需要的管道和柱子最少多少钱。输入保证开始和最后都不是十字路口。

思路:

dp,利用dp[i][0]表示到第i个路口右边的柱子为普通柱子时所需要的最低花费,dp[i][1]第i个路口右边的柱子为高柱子所需要的最低花费,

如果当前路口是1,那么此时路口右边的柱子只能是高柱子
dp[i][1]=max(dp[i-1][1]+a+2*b)

如果当前路口是0,那么右边的柱子可能是普通柱子,也可能是高柱子
如果是普通柱子,
此时左边可能为普通柱子,也可能为高柱子,有:
dp[i][0]=min(dp[i][0],min(dp[i-1][0]+a+b,dp[i-1][1]+2*a+b));

如果是高柱子,
此时左边可能为普通柱子,也可能为高柱子,有:
dp[i][1]=min(dp[i][1],min(dp[i-1][0]+2*a+2*b,dp[i-1][1]+a+b*2));

由于输入数据保证最后不是十字路口,所以最右边一定是普通柱子,也就是dp[n][0]

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
char str[200010];
ll dp[200010][2];
ll inf=0x3f3f3f3f3f3f3f3f;
int main(){
	int t;
	scanf("%d",&t);
	while(t--){
		int n,a,b;
		scanf("%d %d %d",&n,&a,&b);
		getchar();//
		scanf("%s",str+1);
		
		for(int i=0;i<=n;i++) dp[i][0]=dp[i][1]=inf;
		
		dp[0][1]=inf;
		dp[0][0]=b;
		
		for(int i=1;i<=n;i++){
			if(str[i]=='1'){
				dp[i][1]=min(dp[i][1],dp[i-1][1]+a+b*2);
			}
			else{
				dp[i][0]=min(dp[i][0],min(dp[i-1][0]+a+b,dp[i-1][1]+2*a+b));
				dp[i][1]=min(dp[i][1],min(dp[i-1][0]+2*a+2*b,dp[i-1][1]+a+b*2));
			}
		}
		
		printf("%lld\n",dp[n][0]);
	}
	return 0;
}

posted @ 2019-08-24 17:57  xzhws  阅读(50)  评论(0编辑  收藏  举报