1443B Saving the City(贪心)

题目链接

题意

给定两个整数ab。以及一个只包含01的字符串s
1activate需要费用a,将0转变成1需要费用b
另,将连在一起的1activate只需要花费一次的a

问将所有的1activate需要的最少费用。

数据范围:1≤a,b≤1000,s.length< 1 0 5 10^5 105

思路

首先,在第一个1之前出现的0一定不会被转换成1,并且第一个1需要被引爆(与第一个1相连的1都会被引爆,无论引爆连续的1中的哪一个1都会产生同样的效果)

记录从当前1到下一个1之间出现的0的个数(cnt),当碰到s[i] == '1' && s[i - 1] == '0'时,ans += min(cnt*b, a)
a为引爆下一组1cnt*b为拼接上一组的1(这时就不需要再引爆,但需要将0转换成1)

AC的代码

#include <bits/stdc++.h> 
using namespace std;
char s[100003] = "0";// 方便第一个`1`的判断
int inf = 0x3f3f3f3f / 1000;
int main() {
	int t, a, b, cnt;
	long long ans;// 用int会炸
	cin >> t;
	while (t--) {
		cin >> a >> b;
		cnt = inf;// 确保第一个`1`被引爆
		ans = 0;
		scanf("%s", s + 1);
		for (int i = 1; s[i]; ++i)
			if (s[i] == '0') {
				++cnt;
			}
			else {
				if (s[i - 1] == '0')
					ans += min(cnt*b, a);
				cnt = 0;
			}
		cout << ans << endl;
	}
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值