题目大意:有n个整数和一个长度为n的01字符串,1表示选择对应数字,0表示不选,字符串中的1可以选择向左移一个单位或者不动,问1对应所有数字之和的最大值是多少
1<=n<=2e5;1<=a[i]<=1e4
思路:我们发现对于像0111这样一个0后面接几个1的序列,我们可以通过几次操作使0挪到任意的位置,那么这一段的和的最大值就是这4个数中最大的那三个,那么我们可以先求出所有数的和,然后从尾到头遍历,维护当前遍历过的数的最小数,遇到0就减去这个最小数然后重置最小值,这样我们就把每一段0开头的数字的那一段数的最小值都减去了,最后得到的就是和的
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
const int N = 2e5 + 5,INF=0x7fffffff;
char s[N];
int a[N];
int main()
{
int t;
cin >> t;
while (t--)
{
int n;
scanf("%d", &n);
getchar();
for (int i = 1; i <= n; i++)
{
scanf("%c", &s[i]);
}
int ans = 0;
for (int i = 1; i <= n; i++)
{
scanf("%d", &a[i]);
ans += a[i];//统计所有数的和
}
int mi = INF;
for (int i = n; i >= 1; i--)
{
mi = min(mi, a[i]);//维护当前这段数的最小值
if (s[i] == '0')
{
ans -= mi;//遇到0就减去这段数的最小值
mi = INF;//然后重新统计最小值
}
}
printf("%d\n", ans);
}
return 0;
}
最大值