B. Saving the City(字符串+思维)Codeforces Round #681 (Div. 2, based on VK Cup 2019-2020 - Final)
原题链接: https://codeforces.com/contest/1443/problem/B

 测试样例
input
2
1 1
01000010
5 1
01101110
output
2
6
Note
In the second test case, if we place a mine under the fourth building and then activate it, then all mines on the field are activated. The cost of such operations is six, b=1 coin for placing a mine and a=5 coins for activating.
题意: 你需要引爆所有炸弹,现在引爆连续的炸弹需要 a a a花费,在空白区域填炸弹需要 b b b花费,问你最小花费是多少?
解题思路: 贪心问题,我们把字符串看成是有 k k k个连续的’1’字符段,那么我们引爆单独的’1’字符段消耗肯定是为 a a a的,那么如果填充空白区域连接两个单独的字符段比引爆花费更小,那么我们自然会选择空白区域填充 ,所以这无非就是一个字符串遍历问题。考虑哪个更优,要注意计算间距和引爆标志位flag。具体看AC代码。
AC代码
/*
*邮箱:unique_powerhouse@qq.com
*blog:https://me.csdn.net/hzf0701
*注:文章若有任何问题请私信我或评论区留言,谢谢支持。
*
*/
#include<bits/stdc++.h>//POJ不支持
#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=a;i>=n;i--)
using namespace std;
const int inf=0x3f3f3f3f;//无穷大。
const int maxn=1e5;//限定值。
typedef long long ll;
int t,a,b;
string s;
int main(){
	while(cin>>t){
		while(t--){
			cin>>a>>b>>s;
			int len=s.size();
			int pos=0,cnt=5000,ans=0;
			rep(i,0,len-1){
				if(s[i]=='1'){
					//找到第一个连续1的段。
					pos=i;
					break;
				}
			}
			//接下来贪心取最优。
			bool flag=false;//判断这连续段是否点燃了。
			rep(i,pos,len-1){
				if(s[i]=='1'){
					if(!flag){
						ans+=min(a,cnt*b);//取最优。
						flag=true;
						cnt=0;
					}
				}
				else{
					//为0,连续段结束,flag标志位置0。
					flag=false;
					cnt++;
				}
			}
			cout<<ans<<endl;
		}
	}
	return 0;
}

 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号